--- /dev/null
+# -*- coding: utf-8 -*-
+"""
+module de wrapping du synthétiseur
+
+$Id$
+$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, sfPath='') :
+ FSynth.__init__(self, gain=gain, samplerate=samplerate)
+
+ if not sfPath :
+ sfPath = realpath(__file__).split(sep)
+ sfPath = sfPath[:-1]
+ sfPath.append('soundfonts')
+
+ sfPath.append('FluidR3_GM.sf2')
+ sfPath = sep.join(sfPath)
+
+ assert exists(sfPath)
+
+ self.start()
+ self.fsid = self.sfload(sfPath)
+ self._octaveAjusts = {}
+ console.debug('démarrage du synthétiseur')
+ envLogger.info('soundfont : %s', sfPath)
+
+ def __del__(self) :
+ console.debug('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)
+
+ def program_select(self, chan, bank, preset):
+ FSynth.program_select(self, chan, self.fsid, bank, preset)
+
+ def sfont_select(self, chan):
+ FSynth.sfont_select(self, chan, self.fsid)
+
+
+ # 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)