restitution des mouvements du curseur.
[minwii.git] / src / app / synth.py
index a2a0244..469fd04 100755 (executable)
@@ -7,22 +7,46 @@ $URL$
 """
 from os.path import realpath, sep, exists
 from  fluidsynth import Synth as FSynth
+from log import console, envLogger, eventLogger
+import pygame
+import events
 
 class Synth(FSynth) :
+    """
+    Interface fluidsynth avec les adaptations suivantes :
+    - la soundfont FluidR3_GM.sf2 est chargée par défaut
+    - le constructeur démarre le synthé
+    - octaviation
+    """
     
-    def __init__(self, gain=0.2, samplerate=44100) :
+    def __init__(self, gain=0.2, samplerate=44100, sfPath='') :
         FSynth.__init__(self, gain=gain, samplerate=samplerate)
         
-        sfPath = realpath(__file__).split(sep)
-        sfPath = sfPath[:-1]
-        sfPath.append('soundfonts')
+        if not sfPath :
+            sfPath = realpath(__file__).split(sep)
+            sfPath = sfPath[:-1]
+            sfPath.append('soundfonts')
+
+            sfPath.append('FluidR3_GM.sf2')
+            sfPath = sep.join(sfPath)
 
-        sfPath.append('FluidR3_GM.sf2')
-        sfPath = sep.join(sfPath)
         assert exists(sfPath)
 
         self.start()
         self.fsid = self.sfload(sfPath)
+        self._octaveAjusts = {}
+        console.info('démarrage du synthétiseur')
+        envLogger.info('soundfont : %s', sfPath)
+    
+    def __del__(self) :
+        console.info('arrêt du synthétiseur')
+        self.delete()
+    
+    def adjust_octave(self, chan, octave) :
+        '''
+        Abaisse ou élève les notes de n octave
+        '''
+        self._octaveAjusts[chan] = octave
     
     def sfunload(self, update_midi_preset=0):
         FSynth.sfunload(self, self.fsid, update_midi_preset=update_midi_preset)
@@ -33,8 +57,22 @@ class Synth(FSynth) :
     def sfont_select(self, chan):
         FSynth.sfont_select(self, chan, self.fsid)
 
-        
 
-
-if __name__ == '__main__' :
-    initsynth()
\ No newline at end of file
+    # on loggue les noteon / noteoff en utilisant les événements pygame
+    # mais ils ne sont pas postés -> on fait ça pour que le log de l'événement
+    # et l'exécution du noteon/off soit effectué au sein de la même itération
+    # de la boucle principale.
+    
+    def noteon(self, chan, key, vel):
+        key = key + self._octaveAjusts.get(chan, 0) * 12
+        FSynth.noteon(self, chan, key, vel)
+        evt = pygame.event.Event(events.NOTEON, chan=chan, key=key, vel=vel)
+        eventLogger.info(evt)
+        #pygame.event.post(evt)
+    
+    def noteoff(self, chan, key) :
+        key = key + self._octaveAjusts.get(chan, 0) * 12
+        FSynth.noteoff(self, chan, key)
+        evt = pygame.event.Event(events.NOTEOFF, chan=chan, key=key)
+        eventLogger.info(evt)
+        #pygame.event.post(evt)