envoi des événements NOTEON et NOTEOFF du synthé.
[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
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\nsoundfont : %s', sfPath)
39
40 def __del__(self) :
41 console.info('arrêt du synthétiseur.')
42 self.delete()
43
44 def adjust_octave(self, chan, octave) :
45 '''
46 Abaisse ou élève les notes de n octave
47 '''
48 self._octaveAjusts[chan] = octave
49
50 def sfunload(self, update_midi_preset=0):
51 FSynth.sfunload(self, self.fsid, update_midi_preset=update_midi_preset)
52
53 def program_select(self, chan, bank, preset):
54 FSynth.program_select(self, chan, self.fsid, bank, preset)
55
56 def sfont_select(self, chan):
57 FSynth.sfont_select(self, chan, self.fsid)
58
59 def noteon(self, chan, key, vel):
60 key = key + self._octaveAjusts.get(chan, 0) * 12
61 FSynth.noteon(self, chan, key, vel)
62 evt = pygame.event.Event(events.NOTEON, chan=chan, key=key, vel=vel)
63 pygame.event.post(evt)
64
65 def noteoff(self, chan, key) :
66 key = key + self._octaveAjusts.get(chan, 0) * 12
67 FSynth.noteoff(self, chan, key)
68 evt = pygame.event.Event(events.NOTEOFF, chan=chan, key=key)
69 pygame.event.post(evt)