diff options
author | Nat <Nat@localhost.localdomain> | 2007-02-12 19:20:56 (GMT) |
---|---|---|
committer | Nat <Nat@localhost.localdomain> | 2007-02-12 19:20:56 (GMT) |
commit | 1d15172e215d42c7cdf82893f1216ab449a9c1bc (patch) | |
tree | 7ebf93ea00ba265a262fd9e97f1ef12f535f1129 /miniTamTam | |
parent | ed12c41b6edb0a26c861790a79918757807825e9 (diff) |
Renamed Player to miniTamTam
Diffstat (limited to 'miniTamTam')
-rw-r--r-- | miniTamTam/GenRythm.py | 89 | ||||
-rw-r--r-- | miniTamTam/KeyboardStandAlone.py | 118 | ||||
-rw-r--r-- | miniTamTam/NoteStdAlone.py | 103 | ||||
-rw-r--r-- | miniTamTam/RythmGenerator.py | 82 | ||||
-rw-r--r-- | miniTamTam/RythmPlayer.py | 104 | ||||
-rw-r--r-- | miniTamTam/StandalonePlayer.py | 495 | ||||
-rw-r--r-- | miniTamTam/__init__.py | 0 |
7 files changed, 991 insertions, 0 deletions
diff --git a/miniTamTam/GenRythm.py b/miniTamTam/GenRythm.py new file mode 100644 index 0000000..0cba969 --- /dev/null +++ b/miniTamTam/GenRythm.py @@ -0,0 +1,89 @@ +import random +import Config + +from Generation.GenerationConstants import GenerationConstants +from Generation.Utils import * + +class GenRythm: + def __init__( self, instrument, barLength, nbeats ): + self.instrument = instrument + self.barLength = barLength + self.nbeats = nbeats + +############################################################################# + def drumRythmSequence(self, regularity ): + rythmSequence = [] + binSelection = [] + downBeats = [] + upBeats = [] + beats = [] + density = 0.8 + countDown = 0 + onsetTime = None + beatsPerPage = int( self.barLength / Config.TICKS_PER_BEAT ) + + if Config.INSTRUMENTS[ self.instrument ].instrumentRegister == Config.PUNCH: + registerDensity = 0.5 + downBeatRecurence = 4 + for beat in range( beatsPerPage ): + beats.append( beat * Config.TICKS_PER_BEAT ) + for i in range( len( beats ) ): + downBeats.append( ( beats[ GenerationConstants.PUNCH_ACCENTS[ beatsPerPage ][ i ] ], pow( float( len( beats ) - i) / len( beats ), 1.5 ) * 100.) ) + for downBeat in downBeats: + upBeats.append( ( downBeat[ 0 ] + Config.TICKS_PER_BEAT , downBeat[ 1 ] ) ) + + if Config.INSTRUMENTS[ self.instrument ].instrumentRegister == Config.LOW: + registerDensity =1.5 + downBeatRecurence = 4 + for beat in range( beatsPerPage ): + beats.append( beat * Config.TICKS_PER_BEAT ) + for i in range( len( beats ) ): + downBeats.append( ( beats[ GenerationConstants.LOW_ACCENTS[ beatsPerPage ][ i ] ], pow( float( len( beats ) - i) / len( beats ), 1.5 ) * 100.) ) + for downBeat in downBeats: + upBeats.append( ( downBeat[ 0 ] + Config.TICKS_PER_BEAT / 2 , downBeat[ 1 ] ) ) + + if Config.INSTRUMENTS[ self.instrument ].instrumentRegister == Config.MID: + registerDensity = .75 + downBeatRecurence = 1 + for beat in range( beatsPerPage ): + beats.append( beat * Config.TICKS_PER_BEAT ) + beats.append( beat * Config.TICKS_PER_BEAT + ( Config.TICKS_PER_BEAT / 2 ) ) + for i in range( len( beats ) ): + downBeats.append( ( beats[ GenerationConstants.MID_ACCENTS[ beatsPerPage ][ i ] ], pow( float( len( beats ) - i) / len( beats ), 1.5 ) * 100.) ) + for downBeat in downBeats: + upBeats.append( ( downBeat[ 0 ] + Config.TICKS_PER_BEAT / 4 , downBeat[ 1 ] ) ) + + if Config.INSTRUMENTS[ self.instrument ].instrumentRegister == Config.HIGH: + registerDensity = 1.5 + downBeatRecurence = 1 + for beat in range( beatsPerPage ): + beats.append( beat * Config.TICKS_PER_BEAT ) + beats.append( beat * Config.TICKS_PER_BEAT + ( Config.TICKS_PER_BEAT / 2 ) ) + for i in range( len( beats ) ): + downBeats.append( ( beats[ GenerationConstants.HIGH_ACCENTS[ beatsPerPage ][ i ] ], pow( float( len( beats ) - i) / len( beats ), 1.5 ) * 100.) ) + for downBeat in downBeats: + upBeats.append( ( downBeat[ 0 ] + Config.TICKS_PER_BEAT / 4 , downBeat[ 1 ] ) ) + + for i in range( int( density * registerDensity * len( downBeats ) ) ): + if random.randint( 0, 100 ) < ( regularity * 100 * downBeatRecurence ) and binSelection.count( 1 ) < len( downBeats ): + binSelection.append( 1 ) + else: + if binSelection.count( 0 ) < len( downBeats ): + binSelection.append( 0 ) + else: + binSelection.append( 1 ) + + countDown = binSelection.count( 1 ) + + for i in range( countDown ): + while onsetTime in rythmSequence or onsetTime == None: + onsetTime = prob2( downBeats ) + rythmSequence.append( onsetTime ) + + for i in range( len( binSelection ) - countDown ): + while onsetTime in rythmSequence or onsetTime == None: + onsetTime = prob2( upBeats ) + rythmSequence.append( onsetTime ) + + rythmSequence.sort() + return rythmSequence diff --git a/miniTamTam/KeyboardStandAlone.py b/miniTamTam/KeyboardStandAlone.py new file mode 100644 index 0000000..1848971 --- /dev/null +++ b/miniTamTam/KeyboardStandAlone.py @@ -0,0 +1,118 @@ +import pygtk +pygtk.require( '2.0' ) +import gtk + +import Config +#TODO: this is a suprising dependency... what's up?? +from Generation.GenerationConstants import GenerationConstants +from Util.NoteDB import Note +from Util.CSoundNote import CSoundNote +from Util.CSoundClient import new_csound_client + +KEY_MAP_PIANO = Config.KEY_MAP_PIANO + +class KeyboardStandAlone: + def __init__( self, recordingFunction, adjustDurationFunction, getCurrentTick, getPlayState ): + self.csnd = new_csound_client() + self.recording = recordingFunction + self.adjustDuration = adjustDurationFunction +# self.getCurrentTick = getCurrentTick + self.getPlayState = getPlayState + self.key_dict = dict() + self.onset_dict = dict() + self.trackCount = 10 + self.instrument = 'flute' + self.reverb = 0 + + def setInstrument( self , instrument ): + self.instrument = instrument + + def setReverb(self , reverb): + self.reverb = reverb + + def onKeyPress(self,widget,event): + key = event.hardware_keycode + # If the key is already in the dictionnary, exit function (to avoir key repeats) + if self.key_dict.has_key(key): + return + # Assign on which track the note will be created according to the number of keys pressed + track = self.trackCount + self.trackCount += 1 + if self.trackCount >= 20: + self.trackCount = 10 + # If the pressed key is in the keymap + if KEY_MAP_PIANO.has_key(key): + # CsoundNote parameters + pitch = KEY_MAP_PIANO[key] + duration = -1 + instrument = self.instrument + + if event.state == gtk.gdk.MOD1_MASK: + pitch = pitch+5 + + if instrument[ 0: 4 ] == 'drum': + if GenerationConstants.DRUMPITCH.has_key( pitch ): + pitch = GenerationConstants.DRUMPITCH[ pitch ] + + if instrument == 'drum1kit': + instrument = Config.DRUM1INSTRUMENTS[ pitch ] + if instrument == 'drum2kit': + instrument = Config.DRUM2INSTRUMENTS[ pitch ] + if instrument == 'drum3kit': + instrument = Config.DRUM3INSTRUMENTS[ pitch ] + + pitch = 36 + duration = 100 + + if Config.INSTRUMENTS[instrument].csoundInstrumentId == Config.INST_PERC: #Percussions resonance + duration = 60 + + # Create and play the note + self.key_dict[key] = CSoundNote(onset = 0, + pitch = pitch, + amplitude = 1, + pan = 0.5, + duration = duration, + trackId = track, + fullDuration = False, + instrument = instrument, + instrumentFlag = instrument, + reverbSend = self.reverb) + self.csnd.play(self.key_dict[key], 0.3) + #self.key_dict[key].playNow(0.3) + if self.getPlayState(): + recOnset = self.csnd.loopGetTick() / 3 + self.onset_dict[key] = recOnset + self.recording( CSoundNote( + onset = recOnset, + pitch = pitch, + amplitude = 1, + pan = 0.5, + duration = 100, + trackId = track, + decay = .1, + fullDuration = False, + instrument = instrument, + instrumentFlag = instrument, + reverbSend = self.reverb)) + + def onKeyRelease(self,widget,event): + key = event.hardware_keycode + + if KEY_MAP_PIANO.has_key(key): + csnote = self.key_dict[key] + if Config.INSTRUMENTS[ csnote.instrument].csoundInstrumentId == Config.INST_TIED: + csnote.duration = .5 + csnote.decay = 0.7 + csnote.amplitude = 1 + self.csnd.play(csnote, 0.3) + if self.getPlayState(): + self.adjustDuration(csnote.pitch, self.onset_dict[key]) + del self.key_dict[key] + if self.getPlayState(): + if self.onset_dict.has_key(key): + del self.onset_dict[key] + + def onButtonPress( self, widget, event ): + pass + diff --git a/miniTamTam/NoteStdAlone.py b/miniTamTam/NoteStdAlone.py new file mode 100644 index 0000000..1afeb11 --- /dev/null +++ b/miniTamTam/NoteStdAlone.py @@ -0,0 +1,103 @@ +import Config +from Util.CSoundClient import CSoundClient +from Generation.GenerationConstants import GenerationConstants + +class NoteStdAlone: + def __init__( self, client, + onset, + pitch, + amplitude, + pan, + duration, + trackId, + fullDuration = False, + instrument = Config.FLUTE, + attack = 0.005, + decay = 0.095, + reverbSend = 0.1, + filterType = 0, + filterCutoff = 1000, + tied = False, + overlap = False, + instrumentFlag = Config.FLUTE ): + self.csnd = client + self.onset = onset + self.pitch = pitch + self.amplitude = amplitude + self.pan = pan + self.duration = duration + self.trackId = trackId + self.instrument = instrument + self.fullDuration = fullDuration + self.attack = attack + self.decay = decay + self.reverbSend = reverbSend + self.filterType = filterType + self.filterCutoff = filterCutoff + self.tied = tied + self.overlap = overlap + if self.instrument == 'drum1kit': + self.instrumentFlag = Config.DRUM1INSTRUMENTS[ self.pitch ] + else: + self.instrumentFlag = self.instrument + + def play( self ): + self.csnd.sendText( self.getText(120) ) + + def getText( self, tempo ): + if self.instrument[ 0: 4 ] == 'drum': + if GenerationConstants.DRUMPITCH.has_key( self.pitch ): + self.pitch = GenerationConstants.DRUMPITCH[ self.pitch ] + + if self.instrument == 'drum1kit': + self.instrumentFlag = Config.DRUM1INSTRUMENTS[ self.pitch ] + if self.instrument == 'drum2kit': + self.instrumentFlag = Config.DRUM2INSTRUMENTS[ self.pitch ] + if self.instrument == 'drum3kit': + self.instrumentFlag = Config.DRUM3INSTRUMENTS[ self.pitch ] + newPitch = 1 + else: + self.instrumentFlag = self.instrument + newPitch = pow( GenerationConstants.TWO_ROOT_TWELVE, self.pitch - 36 ) + + oneTickDuration = (Config.MS_PER_MINUTE / 1000) / tempo / Config.TICKS_PER_BEAT + + newDuration = oneTickDuration * self.duration + + # condition for tied notes + if Config.INSTRUMENTS[ self.instrumentFlag ].csoundInstrumentId == 101 and self.tied and self.fullDuration: + newDuration = -1 + # condition for overlaped notes + if Config.INSTRUMENTS[ self.instrumentFlag ].csoundInstrumentId == 102 and self.overlap: + newDuration = oneTickDuration * self.duration + 1. + + if True: newAmplitude = self.amplitude * 0.8 + else : newAmplitude = self.amplitude * music_volume_get( self.trackId ) + + newAttack = newDuration * self.attack + if newAttack <= 0.002: + newAttack = 0.002 + + newDecay = newDuration * self.decay + if newDecay <= 0.002: + newDecay = 0.002 + + loopStart = Config.INSTRUMENTS[ self.instrumentFlag ].loopStart + loopEnd = Config.INSTRUMENTS[ self.instrumentFlag ].loopEnd + crossDur = Config.INSTRUMENTS[ self.instrumentFlag ].crossDur + return Config.PLAY_NOTE_COMMAND % ( Config.INSTRUMENTS[ self.instrumentFlag ].csoundInstrumentId, + self.trackId, + 0, + newDuration, + newPitch, + self.reverbSend, + newAmplitude, + self.pan, + Config.INSTRUMENT_TABLE_OFFSET + Config.INSTRUMENTS[ self.instrumentFlag ].instrumentId, + newAttack, + newDecay, + self.filterType, + self.filterCutoff, + loopStart, + loopEnd, + crossDur ) diff --git a/miniTamTam/RythmGenerator.py b/miniTamTam/RythmGenerator.py new file mode 100644 index 0000000..a633ab8 --- /dev/null +++ b/miniTamTam/RythmGenerator.py @@ -0,0 +1,82 @@ +import random +import math + +import Config +from Util.CSoundNote import CSoundNote +from Generation.GenerationConstants import GenerationConstants +from miniTamTam.GenRythm import GenRythm + +def generator( instrument, nbeats, regularity, reverbSend ): + + def makePitchSequence(length, drumPitch): + pitchSequence = [] + for i in range(length): + pitchSequence.append(drumPitch[ random.randint( 0, ( len( drumPitch ) - 1 ) ) ] ) + return pitchSequence + + def makeGainSequence( onsetList ): + gainSequence = [] + for onset in onsetList: + if onset == 0: + gain = random.uniform(GenerationConstants.GAIN_MID_MAX_BOUNDARY, GenerationConstants.GAIN_MAX_BOUNDARY) + elif ( onset % Config.TICKS_PER_BEAT) == 0: + gain = random.uniform(GenerationConstants.GAIN_MID_MIN_BOUNDARY, GenerationConstants.GAIN_MID_MAX_BOUNDARY) + else: + gain = random.uniform(GenerationConstants.GAIN_MIN_BOUNDARY, GenerationConstants.GAIN_MID_MIN_BOUNDARY) + gainSequence.append(gain*2) + return gainSequence + + def makeDurationSequence( onsetList ): + durationSequence = [] + fullDurationSequence = [] + if len( onsetList ) > 1: + for i in range(len(onsetList)): + duration = GenerationConstants.DOUBLE_TICK_DUR / 2 + durationSequence.append(duration) + fullDurationSequence.append(False) + elif len( onsetList ) == 1: + durationSequence.append( GenerationConstants.DOUBLE_TICK_DUR / 2 ) + fullDurationSequence.append( False ) + return durationSequence, fullDurationSequence + + def pageGenerate( regularity, drumPitch ): + barLength = Config.TICKS_PER_BEAT * nbeats + if instrument == 'drum1kit': + currentInstrument = Config.DRUM1INSTRUMENTS[ drumPitch[ 0 ] ] + elif instrument == 'drum2kit': + currentInstrument = Config.DRUM2INSTRUMENTS[ drumPitch[ 0 ] ] + elif instrument == 'drum3kit': + currentInstrument = Config.DRUM3INSTRUMENTS[ drumPitch[ 0 ] ] + + makeRythm = GenRythm( currentInstrument, barLength, nbeats ) + + rythmSequence = makeRythm.drumRythmSequence(regularity) + pitchSequence = makePitchSequence(len(rythmSequence), drumPitch ) + gainSequence = makeGainSequence(rythmSequence) + durationSequence, fullDurationSequence = makeDurationSequence(rythmSequence) + + trackId = 5 + pan = 0.5 + attack = 0.005 + decay = 0.095 + trackNotes = [] + for i in range(len(rythmSequence)): + trackNotes.append( CSoundNote( rythmSequence[i], pitchSequence[i], gainSequence[i], + pan, durationSequence[i], trackId, + fullDurationSequence[i], instrument, attack, decay, reverbSend ) ) + return trackNotes +################################################################################## + # begin generate() + if regularity > 0.75: + pitchOfStream = [ [ 24 ], [30] , [ 40 ], [ 46 ] ] + elif regularity > 0.5: + pitchOfStream = [ [ 24, 28 ], [ 30, 32 ], [ 36, 38, 40 ], [ 46, 48 ] ] + elif regularity > 0.25: + pitchOfStream = [ [ 24, 26, 28 ], [ 30, 32, 34 ], [ 38, 40 ], [ 42, 46, 48 ] ] + else: + pitchOfStream = [ [ 24, 26, 28 ], [ 30, 32, 34 ], [ 38, 40 ], [ 42, 44, 46, 48 ] ] + + trackNotes = [] + for drumPitch in pitchOfStream: + trackNotes.append(pageGenerate( regularity, drumPitch )) + return trackNotes diff --git a/miniTamTam/RythmPlayer.py b/miniTamTam/RythmPlayer.py new file mode 100644 index 0000000..8b339e9 --- /dev/null +++ b/miniTamTam/RythmPlayer.py @@ -0,0 +1,104 @@ +import pygtk +pygtk.require( '2.0' ) +import gtk +import gobject +import time +import Config +from Util.CSoundNote import CSoundNote +from Util.CSoundClient import new_csound_client + +class RythmPlayer: + def __init__( self, recordButtonState ): + self.notesList = [] + self.sequencer = [] + self.pitchs = [] + self.tempo = 120 + self.tickDuration = 60. / self.tempo / 12. + self.tick = 15 + self.csnd = new_csound_client() + self.sequencerPlayback = 0 + self.startLooking = 0 + self.recordState = 0 + self.recordButtonState = recordButtonState + self.playbackTimeout = None + self.beat = 4 + self.playState = 0 + + def setTempo( self, tempo ): + self.tempo = tempo + self.tickDuration = 60. / self.tempo / 12. + gobject.source_remove( self.playBackTimeout ) + self.playState = 0 + self.startPlayback() + + def handleRecordButton( self, widget, data=None ): + if not self.startLooking: + if widget.get_active() == True: + self.beats = [i*4 for i in range(self.beat)] + self.upBeats = [i+2 for i in self.beats] + self.realTick = [i for i in range(self.beat*4)] + self.startLooking = 1 + self.startPlayback() + + def getPlayState( self ): + return self.playState + + def startPlayback( self ): + if not self.playState: + self.playbackTimeout = gobject.timeout_add( int(60000/self.tempo/12), self.handleClock ) + self.handleClock() + self.playState = 1 + + def stopPlayback( self ): + if self.playbackTimeout != None: + gobject.source_remove( self.playbackTimeout ) + self.playbackTimeout = None + self.playState = 0 + + def recording( self, note ): + if self.recordState: + self.pitchs.append( note.pitch ) + self.sequencer.append( note ) + + def adjustDuration( self, pitch, onset ): + if pitch in self.pitchs: + offset = self.csnd.loopGetTick() / 3 + for note in self.sequencer: + if note.pitch == pitch and note.onset == onset: + if offset > note.onset: + note.duration = ( offset - note.onset ) * 3 + 3 + else: + note.duration = ( (offset+(self.beat*4)) - note.onset ) * 3 + 3 + theNote = (note.onset, note) + #sc_loop_addScoreEvent15( theNote ) + self.pitchs.remove( pitch ) + + def handleClock( self ): + t = self.csnd.loopGetTick() / 3 + if self.tick != t: + self.tick = t +# if self.sequencer and self.sequencerPlayback: +# for note in self.sequencer: +# if self.realTick[note.onset] == self.tick: +# self.csnd.sendText(note.getText(self.tickDuration,0)) #play + + if self.startLooking: + self.sequencerPlayback = 0 + if self.tick in self.beats: + self.recordButtonState(True) + if self.tick in self.upBeats: + self.recordButtonState(False) + if self.tick == 0: + self.sequencer = [] + self.pitchs = [] + self.recordState = 1 + self.startLooking = 0 + + if self.tick >= (4 * self.beat - 1): + if self.recordState: + self.recordState = 0 + self.sequencerPlayback = 1 + self.recordButtonState(False) + + return True + diff --git a/miniTamTam/StandalonePlayer.py b/miniTamTam/StandalonePlayer.py new file mode 100644 index 0000000..e40f6d3 --- /dev/null +++ b/miniTamTam/StandalonePlayer.py @@ -0,0 +1,495 @@ +import pygtk +pygtk.require( '2.0' ) +import gtk +import gobject +import os +import random +import time +from types import * + +import Config + +from Util.ThemeWidgets import * +from Util.Credits import Credits +#from Util.NoteLooper import NoteLooper +from Util.CSoundNote import CSoundNote +from Util.NoteDB import Note +from Util.CSoundClient import new_csound_client + +from miniTamTam.KeyboardStandAlone import KeyboardStandAlone +from miniTamTam.RythmPlayer import RythmPlayer +from miniTamTam.RythmGenerator import * +from SynthLab.SynthLabWindow import SynthLabWindow +from Util.Trackpad import Trackpad + +Tooltips = Config.Tooltips + +class StandAlonePlayer( gtk.EventBox ): + + def __init__(self): + gtk.EventBox.__init__( self) + self.set_border_width(Config.MAIN_WINDOW_PADDING) + + self.csnd = new_csound_client() + + self.instrument = self.getInstrumentList()[0] + self.timeout_ms = 50 + self.reverb = 0. + self.volume = 80 + self.regularity = 0.75 + self.beat = 4 + self.tempo = Config.PLAYER_TEMPO + self.rythmInstrument = 'drum1kit' + self.rythmPlayer = RythmPlayer(self.recordStateButton) + self.regenerate() + self.csnd.loopSetTempo(self.tempo) + self.notesList = [] + time.sleep(0.001) + self.playbackTimeout = None + self.trackpad = Trackpad( self, self.csnd ) + + loopPointsTable = [] + sample_names = [name for i in range( len( Config.INSTRUMENTS ) ) for name in Config.INSTRUMENTS.keys() if Config.INSTRUMENTS[ name ].instrumentId == i ] + for inst in sample_names: + loopStart = Config.INSTRUMENTS[ inst ].loopStart + loopEnd = Config.INSTRUMENTS[ inst ].loopEnd + crossDur = Config.INSTRUMENTS[ inst ].crossDur + loopPointsTable.extend( [ loopStart, loopEnd, crossDur ] ) + mess = "f5755 0 512 -2 " + " " .join([str(n) for n in loopPointsTable]) + self.csnd.inputMessage( mess ) + + self.csnd.setMasterVolume(self.volume) + self.rythmPlayer.beat = self.beat + + self.tooltips = gtk.Tooltips() + + self.creditsOpen = False + self.recstate = False + + self.mainWindowBox = gtk.HBox() + self.leftBox = gtk.VBox() + self.rightBox = gtk.VBox() + self.mainWindowBox.add(self.leftBox) + self.mainWindowBox.add(self.rightBox) + self.add(self.mainWindowBox) + + self.enableKeyboard() + self.connect('key-press-event',self.handleKeyboard) + self.setInstrument(self.instrument) + + self.drawInstrumentButtons() + self.drawMicBox() + self.drawSliders() + #self.drawLogo() + self.drawGeneration() + self.show_all() + self.playStartupSound() + + self.synthLabWindow = None + + def drawLogo(self): + eventbox = gtk.EventBox() + eventbox.connect('button-press-event', self.handleLogoPress) + logo = gtk.Image() + logo.set_from_file(Config.IMAGE_ROOT + 'tamtam_rouge.png') + eventbox.add(logo) + self.middleBox.add(eventbox) + + def handleLogoPress(self, widget, event): + pos = widget.window.get_origin() + if self.creditsOpen is False: + credits = Credits(self.handleCreditsClose , pos) + self.handleCreditsClose(True) + + def handleCreditsClose(self , state): + self.creditsOpen = state + + def drawSliders( self ): + mainSliderBox = RoundHBox(fillcolor = Config.PANEL_COLOR, bordercolor = Config.PANEL_BCK_COLOR, radius = Config.PANEL_RADIUS) + mainSliderBox.set_border_width(Config.PANEL_SPACING) + + reverbSliderBox = gtk.HBox() + self.reverbSliderBoxImgTop = gtk.Image() + self.reverbSliderBoxImgTop.set_from_file(Config.IMAGE_ROOT + 'reverb0.png') + reverbAdjustment = gtk.Adjustment(value=self.reverb, lower=0, upper=1, step_incr=0.1, page_incr=0, page_size=0) + reverbSlider = ImageHScale( Config.IMAGE_ROOT + "sliderbutred.png", reverbAdjustment, 7 ) + reverbSlider.set_inverted(False) + reverbSlider.set_size_request(350,15) + reverbAdjustment.connect("value_changed" , self.handleReverbSlider) + reverbSliderBox.pack_start(reverbSlider, True, 20) + reverbSliderBox.pack_start(self.reverbSliderBoxImgTop, False, padding=0) + self.tooltips.set_tip(reverbSlider,Tooltips.REV) + + volumeSliderBox = gtk.HBox() + self.volumeSliderBoxImgTop = gtk.Image() + self.volumeSliderBoxImgTop.set_from_file(Config.IMAGE_ROOT + 'volume2.png') + volumeAdjustment = gtk.Adjustment(value=self.volume, lower=0, upper=100, step_incr=1, page_incr=0, page_size=0) + volumeSlider = ImageHScale( Config.IMAGE_ROOT + "sliderbutviolet.png", volumeAdjustment, 7 ) + volumeSlider.set_inverted(False) + volumeSlider.set_size_request(350,15) + volumeAdjustment.connect("value_changed" , self.handleVolumeSlider) + volumeSliderBox.pack_start(volumeSlider, True, 20) + volumeSliderBox.pack_start(self.volumeSliderBoxImgTop, False, padding=0) + self.tooltips.set_tip(volumeSlider,Tooltips.VOL) + + mainSliderBox.pack_start(volumeSliderBox, True, True, 5) + mainSliderBox.pack_start(reverbSliderBox, True, True, 5) + + self.leftBox.add(mainSliderBox) + + def drawGeneration( self ): + + slidersBox = RoundVBox(fillcolor = Config.PANEL_COLOR, bordercolor = Config.PANEL_BCK_COLOR, radius = Config.PANEL_RADIUS) + slidersBox.set_border_width(Config.PANEL_SPACING) + geneButtonBox = RoundHBox(fillcolor = Config.PANEL_COLOR, bordercolor = Config.PANEL_BCK_COLOR, radius = Config.PANEL_RADIUS) + geneButtonBox.set_border_width(Config.PANEL_SPACING) + transportBox = RoundHBox(fillcolor = Config.PANEL_COLOR, bordercolor = Config.PANEL_BCK_COLOR, radius = Config.PANEL_RADIUS) + transportBox.set_border_width(Config.PANEL_SPACING) + + geneSliderBox = gtk.VBox() + self.geneSliderBoxImgTop = gtk.Image() + self.geneSliderBoxImgTop.set_from_file(Config.IMAGE_ROOT + 'complex6.png') + geneAdjustment = gtk.Adjustment(value=self.regularity, lower=0, upper=1, step_incr=0.01, page_incr=0, page_size=0) + geneSlider = ImageVScale( Config.IMAGE_ROOT + "sliderbutbleu.png", geneAdjustment, 5 ) + geneSlider.set_inverted(False) + geneSlider.set_size_request(15,408) + geneAdjustment.connect("value_changed" , self.handleGenerationSlider) + geneSlider.connect("button-release-event", self.handleGenerationSliderRelease) + geneSliderBox.pack_start(self.geneSliderBoxImgTop, False, padding=10) + geneSliderBox.pack_start(geneSlider, True, 20) + self.tooltips.set_tip(geneSlider,Tooltips.COMPL) + + beatSliderBox = gtk.VBox() + self.beatSliderBoxImgTop = gtk.Image() + self.beatSliderBoxImgTop.set_from_file(Config.IMAGE_ROOT + 'beat3.png') + beatAdjustment = gtk.Adjustment(value=self.beat, lower=2, upper=12, step_incr=1, page_incr=0, page_size=0) + beatSlider = ImageVScale( Config.IMAGE_ROOT + "sliderbutjaune.png", beatAdjustment, 5, snap = 1 ) + beatSlider.set_inverted(True) + beatSlider.set_size_request(15,408) + beatAdjustment.connect("value_changed" , self.handleBeatSlider) + beatSlider.connect("button-release-event", self.handleBeatSliderRelease) + beatSliderBox.pack_start(self.beatSliderBoxImgTop, False, padding=10) + beatSliderBox.pack_start(beatSlider, True, 20) + self.tooltips.set_tip(beatSlider,Tooltips.BEAT) + + tempoSliderBox = gtk.VBox() + self.tempoSliderBoxImgTop = gtk.Image() + self.tempoSliderBoxImgTop.set_from_file(Config.IMAGE_ROOT + 'tempo5.png') + tempoAdjustment = gtk.Adjustment(value=self.tempo, lower=Config.PLAYER_TEMPO_LOWER, upper=Config.PLAYER_TEMPO_UPPER, step_incr=1, page_incr=1, page_size=1) + tempoSlider = ImageVScale( Config.IMAGE_ROOT + "sliderbutvert.png", tempoAdjustment, 5) + tempoSlider.set_inverted(True) + tempoSlider.set_size_request(15,408) + tempoAdjustment.connect("value_changed" , self.handleTempoSliderChange) + tempoSlider.connect("button-release-event", self.handleTempoSliderRelease) + tempoSliderBox.pack_start(self.tempoSliderBoxImgTop, False, padding=10) + tempoSliderBox.pack_start(tempoSlider, True) + self.tooltips.set_tip(tempoSlider,Tooltips.TEMPO) + + slidersBoxSub = gtk.HBox() + slidersBoxSub.pack_start(geneSliderBox) + slidersBoxSub.pack_start(beatSliderBox) + slidersBoxSub.pack_start(tempoSliderBox) + slidersBox.pack_start(slidersBoxSub) + + generateBtn = ImageButton(Config.IMAGE_ROOT + 'dice.png', clickImg_path = Config.IMAGE_ROOT + 'diceblur.png') + generateBtn.connect('clicked', self.handleGenerateBtn) + slidersBox.pack_start(generateBtn) + self.tooltips.set_tip(generateBtn,Tooltips.GEN) + + #Generation Button Box + geneSubBox = gtk.VBox() + geneSubBoxTop = gtk.HBox() + + generationDrumBtn1 = ImageRadioButton(group = None , mainImg_path = Config.IMAGE_ROOT + 'drum1kit.png' , altImg_path = Config.IMAGE_ROOT + 'drum1kitselgen.png') + generationDrumBtn1.connect('clicked' , self.handleGenerationDrumBtn , 'drum1kit') + geneSubBoxTop.pack_start(generationDrumBtn1) + generationDrumBtn2 = ImageRadioButton(group = generationDrumBtn1 , mainImg_path = Config.IMAGE_ROOT + 'drum2kit.png' , altImg_path = Config.IMAGE_ROOT + 'drum2kitselgen.png') + generationDrumBtn2.connect('clicked' , self.handleGenerationDrumBtn , 'drum2kit') + geneSubBoxTop.pack_start(generationDrumBtn2) + generationDrumBtn3 = ImageRadioButton(group = generationDrumBtn1 , mainImg_path = Config.IMAGE_ROOT + 'drum3kit.png' , altImg_path = Config.IMAGE_ROOT + 'drum3kitselgen.png') + generationDrumBtn3.connect('clicked' , self.handleGenerationDrumBtn , 'drum3kit') + geneSubBox.pack_start(geneSubBoxTop, True) + geneSubBox.pack_start(generationDrumBtn3, True) + geneButtonBox.pack_start(geneSubBox, True) + self.tooltips.set_tip(generationDrumBtn1,Tooltips.JAZZ) + self.tooltips.set_tip(generationDrumBtn2,Tooltips.ARAB) + self.tooltips.set_tip(generationDrumBtn3,Tooltips.AFRI) + + #Transport Button Box + self.seqRecordButton = ImageToggleButton(Config.IMAGE_ROOT + 'record2.png', Config.IMAGE_ROOT + 'record2sel.png') + self.seqRecordButton.connect('clicked', self.rythmPlayer.handleRecordButton ) + + self.playStopButton = ImageToggleButton(Config.IMAGE_ROOT + 'play.png', Config.IMAGE_ROOT + 'stop.png') + self.playStopButton.connect('clicked' , self.handlePlayButton) + transportBox.pack_start(self.seqRecordButton) + transportBox.pack_start(self.playStopButton) + self.tooltips.set_tip(self.seqRecordButton,Tooltips.SEQ) + self.tooltips.set_tip(self.playStopButton,Tooltips.PLAY) + + self.rightBox.pack_start(slidersBox, True) + self.rightBox.pack_start(geneButtonBox, True) + self.rightBox.pack_start(transportBox, True) + + + def drawInstrumentButtons(self): + ROW_LEN = 8 + + vBox = gtk.VBox() + + intrumentNum = len(self.getInstrumentList()) + rows = ( intrumentNum // ROW_LEN ) + if intrumentNum % ROW_LEN is not 0: #S'il y a un reste + rows = rows + 1 + + self.firstInstButton = None + for row in range(rows): + hBox = gtk.HBox() + for instrument in self.getInstrumentList()[row*ROW_LEN:(row+1)*ROW_LEN]: + instBox = RoundVBox(fillcolor = Config.INST_BCK_COLOR, bordercolor = Config.PANEL_BCK_COLOR, radius = Config.PANEL_RADIUS) + instBox.set_border_width(Config.PANEL_SPACING) + instButton = ImageRadioButton(self.firstInstButton, Config.IMAGE_ROOT + instrument + '.png' , Config.IMAGE_ROOT + instrument + 'sel.png', Config.IMAGE_ROOT + instrument + 'sel.png') + if self.firstInstButton == None: + self.firstInstButton = instButton + instButton.connect('clicked' , self.handleInstrumentButtonClick , instrument) + instBox.add(instButton) + hBox.add(instBox) + vBox.add(hBox) + self.leftBox.add(vBox) + + def drawMicBox( self ): + hbox = gtk.HBox() + + for n in ['mic1','mic2','mic3','mic4']: + vbox1 = RoundVBox(fillcolor = Config.INST_BCK_COLOR, bordercolor = Config.PANEL_BCK_COLOR, radius = Config.PANEL_RADIUS) + vbox1.set_border_width(Config.PANEL_SPACING) + + micBtn = ImageRadioButton(self.firstInstButton, Config.IMAGE_ROOT + n + '.png' , Config.IMAGE_ROOT + n + 'sel.png', Config.IMAGE_ROOT + n + 'sel.png') + micRecBtn = ImageButton(Config.IMAGE_ROOT + 'record.png' , Config.IMAGE_ROOT + 'recordhi.png', Config.IMAGE_ROOT + 'recordsel.png') + self.tooltips.set_tip(micRecBtn,Tooltips.RECMIC) + + micBtn.connect('clicked', self.handleInstrumentButtonClick, n) + micRecBtn.connect('clicked', self.handleMicButtonClick, n) + micRecBtn.connect('pressed', self.handleRecButtonPress, micBtn) + + vbox1.add(micRecBtn) + vbox1.add(micBtn) + hbox.add(vbox1) + + for n in ['lab1','lab2','lab3','lab4']: + vbox2 = RoundVBox(fillcolor = Config.INST_BCK_COLOR, bordercolor = Config.PANEL_BCK_COLOR, radius = Config.PANEL_RADIUS) + vbox2.set_border_width(Config.PANEL_SPACING) + + synthBtn = ImageRadioButton(self.firstInstButton, Config.IMAGE_ROOT + n + '.png', Config.IMAGE_ROOT + n + 'sel.png', Config.IMAGE_ROOT + n + 'sel.png') + synthRecBtn = ImageButton(Config.IMAGE_ROOT + 'record.png' , Config.IMAGE_ROOT + 'recordhi.png', Config.IMAGE_ROOT + 'recordsel.png') + self.tooltips.set_tip(synthRecBtn,Tooltips.RECLAB) + + synthBtn.connect('clicked', self.handleInstrumentButtonClick, n) + synthRecBtn.connect('clicked', self.handleSynthButtonClick, n) + synthRecBtn.connect('pressed', self.handleRecButtonPress, synthBtn) + + vbox2.add(synthRecBtn) + vbox2.add(synthBtn) + hbox.add(vbox2) + + self.leftBox.add(hbox) + + def recordStateButton( self, state ): + self.seqRecordButton.set_active( state ) + + def handleInstrumentButtonClick(self , widget , instrument): + if widget.get_active() == True and self.recstate == False: + self.setInstrument(instrument) + self.playInstrumentNote(instrument) + + def handleRecButtonPress(self, widget, recBtn): + self.recstate = True + recBtn.set_active(True) + + def synthLabWindowOpen(self): + return self.synthLabWindow != None and self.synthLabWindow.get_property('visible') + + def handleMicButtonClick(self , widget , data): + self.recstate = False + self.setInstrument(data) + os.system('rm ' + Config.PREF_DIR + '/' + data) + if data == 'mic1': + self.csnd.micRecording(7) + elif data == 'mic2': + self.csnd.micRecording(8) + elif data == 'mic3': + self.csnd.micRecording(9) + elif data == 'mic4': + self.csnd.micRecording(10) + else: + return + self.micTimeout = gobject.timeout_add(5000, self.loadMicInstrument, data) + + def loadMicInstrument( self, data ): + self.csnd.load_mic_instrument( data ) + + def handleSynthButtonClick(self , widget , data): + self.recstate = False + self.setInstrument(data) + if self.synthLabWindow != None: + self.synthLabWindow.destroy() + self.synthLabWindow =None + + self.synthLabWindow = SynthLabWindow( + {'lab1':86, 'lab2':87, 'lab3':88, 'lab4':89}[data], + self.closeSynthLab) + self.synthLabWindow.show_all() + + def closeSynthLab(self): + if self.synthLabWindow != None: + self.synthLabWindow.destroy() + self.synthLabWindow = None + + def regenerate(self): + def flatten(ll): + rval = [] + for l in ll: + rval += l + return rval + i = 0 + self.noteList= [] + self.csnd.loopClear() + for x in flatten( generator(self.rythmInstrument, self.beat, self.regularity, self.reverb) ): + n = Note(0, x.trackId, i, x) + self.noteList.append( (x.onset, n) ) + i = i + 1 + self.csnd.loopPlay(n) + self.csnd.loopSetNumTicks( self.beat * Config.TICKS_PER_BEAT) + + def handleGenerationSlider(self, adj): + img = int(adj.value * 7)+1 + self.geneSliderBoxImgTop.set_from_file(Config.IMAGE_ROOT + 'complex' + str(img) + '.png') + + def handleGenerationSliderRelease(self, widget, event): + self.regularity = widget.get_adjustment().value + self.regenerate() + + def handleBeatSlider(self, adj): + img = self.scale(int(adj.value),2,12,1,11) + self.beatSliderBoxImgTop.set_from_file(Config.IMAGE_ROOT + 'beat' + str(img) + '.png') + + def handleBeatSliderRelease(self, widget, event): + self.beat = int(widget.get_adjustment().value) + self.rythmPlayer.beat = self.beat + self.regenerate() + + def handleTempoSliderRelease(self, widget, event): + #self.tempo = int(widget.get_adjustment().value) + #self.csnd.loopSetTempo(self.tempo) + pass + + def handleTempoSliderChange(self,adj): + self.tempo = int(adj.value) + self.csnd.loopSetTempo(self.tempo) + + img = int(self.scale( self.tempo, + Config.PLAYER_TEMPO_LOWER,Config.PLAYER_TEMPO_UPPER, + 1,8)) + self.tempoSliderBoxImgTop.set_from_file(Config.IMAGE_ROOT + 'tempo' + str(img) + '.png') + + + def handleVolumeSlider(self, adj): + self.volume = int(adj.value) + self.csnd.setMasterVolume(self.volume) + img = int(self.scale(self.volume,0,100,0,3.9)) + self.volumeSliderBoxImgTop.set_from_file(Config.IMAGE_ROOT + 'volume' + str(img) + '.png') + + def handleReverbSlider(self, adj): + self.reverb = adj.value + img = int(self.scale(self.reverb,0,1,0,4)) + self.reverbSliderBoxImgTop.set_from_file(Config.IMAGE_ROOT + 'reverb' + str(img) + '.png') + self.keyboardStandAlone.setReverb(self.reverb) + + def handlePlayButton(self, widget, data = None): + if widget.get_active() == False: + self.rythmPlayer.stopPlayback() + self.playbackTimeout = None + self.csnd.loopStop() + else: + self.csnd.loopSetTick(0) + self.csnd.loopStart() + + + def handleGenerationDrumBtn(self , widget , data): + #data is drum1kit, drum2kit, or drum3kit + self.rythmInstrument = data + for (o,n) in self.notesList : + n.instrumentFlag = data + self.csnd.loopSet_onset_note( self.notesList) + + def handleGenerateBtn(self , widget , data=None): + self.regenerate() + if self.playbackTimeout == None : + self.playStopButton.set_active(True) #this calls handlePlayButton + self.playStartupSound() + + def enableKeyboard( self ): + self.keyboardStandAlone = KeyboardStandAlone( self.rythmPlayer.recording, self.rythmPlayer.adjustDuration, self.csnd.loopGetTick, self.rythmPlayer.getPlayState ) + self.add_events(gtk.gdk.BUTTON_PRESS_MASK) + + def setInstrument( self , instrument ): + self.instrument = instrument + self.keyboardStandAlone.setInstrument(instrument) + + def playInstrumentNote(self , instrument, secs_per_tick = 0.025): + self.csnd.play( + CSoundNote( onset = 0, + pitch = 36, + amplitude = 1, + pan = 0.5, + duration = 20, + trackId = 1, + fullDuration = False, + instrument = instrument, + instrumentFlag = instrument, + reverbSend = 0), + secs_per_tick) + + def handleKeyboard(self, widget, event): + if event.hardware_keycode == 65: + if self.playStopButton.get_active(): + self.playStopButton.set_active(False) + else: + self.playStopButton.set_active(True) + + def playStartupSound(self): + r = str(random.randrange(1,11)) + self.playInstrumentNote('guidice' + r) + + def getInstrumentList(self): + cleanInstrumentList = [instrument for instrument in Config.INSTRUMENTS.keys() if instrument[0:4] != 'drum' and instrument[0:3] != 'mic' and instrument[0:3] != 'lab' and instrument[0:4] != 'guid'] + cleanInstrumentList.sort(lambda g,l: cmp(Config.INSTRUMENTS[g].category, Config.INSTRUMENTS[l].category) ) + return cleanInstrumentList + ['drum1kit', 'drum2kit', 'drum3kit'] + + def destroy( self, widget ): + gtk.main_quit() + + def scale(self, input,input_min,input_max,output_min,output_max): + range_input = input_max - input_min + range_output = output_max - output_min + result = (input - input_min) * range_output / range_input + output_min + + if (input_min > input_max and output_min > output_max) or (output_min > output_max and input_min < input_max): + if result > output_min: + return output_min + elif result < output_max: + return output_max + else: + return result + + if (input_min < input_max and output_min < output_max) or (output_min < output_max and input_min > input_max): + if result > output_max: + return output_max + elif result < output_min: + return output_min + else: + return result + +if __name__ == "__main__": + standAlonePlayer = StandAlonePlayer() + #start the gtk event loop + gtk.main() diff --git a/miniTamTam/__init__.py b/miniTamTam/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/miniTamTam/__init__.py |