469fd0445975ca48a4479f68c0760520910620e8
[minwii.git] / src / app / synth.py
1 # -*- coding: utf-8 -*-
2 """
3 module de wrapping du synthétiseur
4
5 $Id$
6 $URL$
7 """
8 from os.path import realpath, sep, exists
9 from fluidsynth import Synth as FSynth
10 from log import console, envLogger, eventLogger
11 import pygame
12 import events
13
14 class Synth(FSynth) :
15 """
16 Interface fluidsynth avec les adaptations suivantes :
17 - la soundfont FluidR3_GM.sf2 est chargée par défaut
18 - le constructeur démarre le synthé
19 - octaviation
20 """
21
22 def __init__(self, gain=0.2, samplerate=44100, sfPath='') :
23 FSynth.__init__(self, gain=gain, samplerate=samplerate)
24
25 if not sfPath :
26 sfPath = realpath(__file__).split(sep)
27 sfPath = sfPath[:-1]
28 sfPath.append('soundfonts')
29
30 sfPath.append('FluidR3_GM.sf2')
31 sfPath = sep.join(sfPath)
32
33 assert exists(sfPath)
34
35 self.start()
36 self.fsid = self.sfload(sfPath)
37 self._octaveAjusts = {}
38 console.info('démarrage du synthétiseur')
39 envLogger.info('soundfont : %s', sfPath)
40
41 def __del__(self) :
42 console.info('arrêt du synthétiseur')
43 self.delete()
44
45 def adjust_octave(self, chan, octave) :
46 '''
47 Abaisse ou élève les notes de n octave
48 '''
49 self._octaveAjusts[chan] = octave
50
51 def sfunload(self, update_midi_preset=0):
52 FSynth.sfunload(self, self.fsid, update_midi_preset=update_midi_preset)
53
54 def program_select(self, chan, bank, preset):
55 FSynth.program_select(self, chan, self.fsid, bank, preset)
56
57 def sfont_select(self, chan):
58 FSynth.sfont_select(self, chan, self.fsid)
59
60
61 # on loggue les noteon / noteoff en utilisant les événements pygame
62 # mais ils ne sont pas postés -> on fait ça pour que le log de l'événement
63 # et l'exécution du noteon/off soit effectué au sein de la même itération
64 # de la boucle principale.
65
66 def noteon(self, chan, key, vel):
67 key = key + self._octaveAjusts.get(chan, 0) * 12
68 FSynth.noteon(self, chan, key, vel)
69 evt = pygame.event.Event(events.NOTEON, chan=chan, key=key, vel=vel)
70 eventLogger.info(evt)
71 #pygame.event.post(evt)
72
73 def noteoff(self, chan, key) :
74 key = key + self._octaveAjusts.get(chan, 0) * 12
75 FSynth.noteoff(self, chan, key)
76 evt = pygame.event.Event(events.NOTEOFF, chan=chan, key=key)
77 eventLogger.info(evt)
78 #pygame.event.post(evt)