nettoyage / implémentation de la méthode update.
[minwii.git] / src / songs / synth.py
1 # -*- coding: utf-8 -*-
2 """
3 module pour jouer les chansons sur le fluidsynth
4
5 $Id$
6 $URL$
7 """
8 import fluidsynth
9 from musicxmltosong import musicXml2Song
10 from time import sleep
11 import sys
12 from optparse import OptionParser
13
14 class SongPlayer(object) :
15 """ Lecteur audio d'une chanson """
16
17 def __init__(self, part, soundFont, quarterNoteDuration=400, bank=0, preset=0) :
18 self.part = part
19 self.quarterNoteDuration = quarterNoteDuration
20 self.fs = fs = fluidsynth.Synth()
21 fs.start()
22 self.fsid = fsid = fs.sfload(soundFont)
23 fs.program_select(0, fsid, bank, preset)
24
25 def __del__(self) :
26 self.fs.delete()
27
28 def play(self) :
29 fs = self.fs
30 for note, verseIndex in self.part.iterNotes(indefinitely=False) :
31 print note, note.lyrics[verseIndex]
32 fs.noteon(0, note.midi, 64)
33 duration = note.duration * self.quarterNoteDuration / 1000
34 sleep(duration)
35 fs.noteoff(0, note.midi)
36
37
38
39
40
41 def main() :
42 usage = "%prog musicXmlFile.xml [options]"
43 op = OptionParser(usage)
44 op.add_option("-i", "--part-index", dest="partIndex"
45 , default = 0
46 , help = "Index de la partie qui contient le champ.")
47 op.add_option("-q", "--quarter-note-duration", dest="quarterNoteDuration"
48 , type="int", default=400
49 , help="Durée de la noire [default] (en millisecondes)"
50 )
51 op.add_option("-b", "--bank", dest="bank"
52 , type="int", default="0"
53 , help="midi bank [default]")
54 op.add_option("-p", "--preset", dest="preset"
55 , type="int", default="0"
56 , help="midi preset [default]")
57
58 options, args = op.parse_args()
59
60 if len(args) != 1 :
61 raise SystemExit(op.format_help())
62
63 song = musicXml2Song(args[0], partIndex=options.partIndex)
64 sp = SongPlayer(song,
65 '/Users/pinbe/dev/minwii/fluid-soundfont-3.1/FluidR3_GM.sf2',
66 quarterNoteDuration=options.quarterNoteDuration,
67 bank = options.bank,
68 preset = options.preset)
69 sp.play()
70
71
72 if __name__ == '__main__' :
73 sys.exit(main())