0832b90357fc377d94981f1c8238f74b04a3534c
[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 app.musicxml 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 try :
32 print note, note.lyrics[verseIndex]
33 except IndexError :
34 print note, '?'
35 fs.noteon(0, note.midi, 64)
36 duration = note.duration * self.quarterNoteDuration / 1000
37 sleep(duration)
38 fs.noteoff(0, note.midi)
39
40
41
42
43
44 def main() :
45 usage = "%prog musicXmlFile.xml [options]"
46 op = OptionParser(usage)
47 op.add_option("-i", "--part-index", dest="partIndex"
48 , default = 0
49 , help = "Index de la partie qui contient le champ.")
50
51 op.add_option("-c", '--no-chorus', dest='autoDetectChorus'
52 , action="store_false"
53 , default = True
54 , help = "désactive la détection du refrain")
55
56 op.add_option("-q", "--quarter-note-duration", dest="quarterNoteDuration"
57 , type="int", default=400
58 , help="Durée de la noire [default] (en millisecondes)"
59 )
60
61 op.add_option("-b", "--bank", dest="bank"
62 , type="int", default="0"
63 , help="midi bank [default]")
64
65 op.add_option("-p", "--preset", dest="preset"
66 , type="int", default="0"
67 , help="midi preset [default]")
68
69 options, args = op.parse_args()
70
71 if len(args) != 1 :
72 raise SystemExit(op.format_help())
73
74 song = musicXml2Song(args[0],
75 partIndex=options.partIndex,
76 autoDetectChorus=options.autoDetectChorus)
77 sp = SongPlayer(song,
78 '/Users/pinbe/dev/minwii/fluid-soundfont-3.1/FluidR3_GM.sf2',
79 quarterNoteDuration=options.quarterNoteDuration,
80 bank = options.bank,
81 preset = options.preset)
82 sp.play()
83
84
85 if __name__ == '__main__' :
86 sys.exit(main())