X-Git-Url: https://scm.cri.ensmp.fr/git/minwii.git/blobdiff_plain/e7854ed82aa375273bfbf772493739f875817061..46f3ffd7fdde386f41020171b5733e55a8e64a85:/src/minwii/synth.py?ds=sidebyside diff --git a/src/minwii/synth.py b/src/minwii/synth.py new file mode 100755 index 0000000..c1faee7 --- /dev/null +++ b/src/minwii/synth.py @@ -0,0 +1,78 @@ +# -*- 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)