c018eaec353e3e41e8a0f9760ef2f18879eb94cf
[minwii.git] / src / songs / Song.py
1 '''
2 Created on 2 oct. 2009
3
4 @author: samsam
5 '''
6 import pickle
7 import os.path
8 from MidiToSong import MidiToSong
9 from mxmMidi.MidiInFile import MidiInFile
10
11 class Song:
12 '''
13 classdocs
14 '''
15
16
17 def __init__(self,scale,notesInExtendedScale=[], requiresExtendedScale = False,midiNoteNumbers = None, alterationIndexes = None, alterations = None, modulationIndexes = None, modulationScales = None, lyrics =None, noteLengths = None, quarterNoteLength = 750, name = "unknownSong"):
18 '''
19 Constructor
20 '''
21 self.name = name
22 self.scale = scale
23 self.notes = notesInExtendedScale
24 self.lyrics = lyrics
25 self.noteLengths = noteLengths
26 self.quarterNoteLength = quarterNoteLength
27 if midiNoteNumbers == None :
28 self.midiNoteNumbers = [self.scale[note] for note in self.notes]
29 else:
30 self.midiNoteNumbers = midiNoteNumbers
31 if self.notes == [] :
32 self.assignNotesFromMidiNoteNumbers()
33 self.requiresExtendedScale = requiresExtendedScale
34 if alterationIndexes != None and alterations != None :
35 self.alterNotes(alterationIndexes, alterations)
36 if modulationIndexes != None and modulationScales != None :
37 self.modulate(modulationIndexes, modulationScales)
38
39 def getSongIterator(self):
40 while True:
41 for i in range(len(self.notes)):
42 if self.lyrics :
43 lyrics = self.lyrics[i]
44 else :
45 lyrics = None
46
47 if self.noteLengths :
48 noteLength = self.noteLengths[i]
49 else :
50 noteLength = 1
51
52 yield [self.notes[i],self.midiNoteNumbers[i],lyrics,noteLength]
53
54 def alterNotes(self,noteIndexes,alterations):
55 for i in range(len(noteIndexes)) :
56 self.midiNoteNumbers[noteIndexes[i]] = self.midiNoteNumbers[noteIndexes[i]] + alterations[i]
57
58 def modulate(self,modulationIndexes,scales):
59 for i in range(len(scales)):
60 if i < len(scales)-1 :
61 bound = modulationIndexes[i+1]
62 else :
63 bound = len(self.notes)
64 for j in range(modulationIndexes[i],bound):
65 self.midiNoteNumbers[j]=scales[i][self.notes[j]]
66
67 def assignNotesFromMidiNoteNumbers(self):
68 for i in range(len(self.midiNoteNumbers)):
69 noteInExtendedScale = 0
70 while self.midiNoteNumbers[i] > self.scale[noteInExtendedScale] and noteInExtendedScale < len(self.scale)-1:
71 noteInExtendedScale += 1
72 if self.midiNoteNumbers[i]<self.scale[noteInExtendedScale]:
73 noteInExtendedScale -= 1
74 self.notes.append(noteInExtendedScale)
75
76 def save(self,path = None):
77 if path == None :
78 path = "".join(os.path.join("smwis",self.name),".swmi")
79 f = file(path, 'w')
80 pickler = pickle.Pickler(f)
81 pickler.dump(self)
82 f.close()
83
84 def loadSongFromMidi(filePath,scale):
85 # get data
86 test_file = '../songs/midis/test.mid'
87 f = open(test_file, 'rb')
88
89 # do parsing
90 mts = MidiToSong()
91 midiIn = MidiInFile(mts, f)
92 midiIn.read()
93 f.close()
94
95 s = Song(scale,midiNoteNumbers = mts.midiNoteNumbers,quarterNoteLength = mts.quarterNoteLength,noteLengths = mts.noteLengths)
96 for nn in s.notes :
97 if nn < 3 :
98 s.requiresExtendedScale = True
99 return(s)
100
101 def loadSong(filePath):
102 f = file(filePath, 'r')
103 unpickler = pickle.Unpickler(f)
104 s = unpickler.load()
105 f.close()
106 return(s)
107
108 if __name__ == '__main__':
109
110 # get data
111 test_file = '../songs/midis/boheme.mid'
112 f = open(test_file, 'rb')
113
114 # do parsing
115 from mxmMidi.MidiInFile import MidiInFile
116 mts = MidiToSong()
117 midiIn = MidiInFile(mts, f)
118 midiIn.read()
119 f.close()
120
121 majorScale = [55, 57, 59, 60, 62, 64, 65, 67, 69, 71, 72]
122
123 s = Song(majorScale,requiresExtendedScale = True, midiNoteNumbers = mts.midiNoteNumbers,quarterNoteLength = mts.quarterNoteLength,noteLengths = mts.noteLengths)
124 for i in range(len(s.midiNoteNumbers)):
125 print "note number :" + str(s.midiNoteNumbers[i]) + ", assigned note :" + str(s.notes[i]) + ", duration :" + str(s.noteLengths[i])
126
127 s.lyrics = ["je","vous","par-","-le","d'un","temps","que","les","moins","de","vingt","ans","ne","peu-","-vent","pas","con-","-nai-","-tre","Mont-","-martre","en","ce","temps","la","ac-","-cro-","-chait","ses","li-","-las","jus-","-que","sous","nos","fe-","-netres","et","si","l'hum-","-ble","gar-","-ni","qui","nous","ser-","-vait","de","nid","ne","pay-","-yait","pas","de","mi-","-ne","c'est","la","qu'on","s'est","con-","-nus","moi","qui","cri-","-ait","fa-","-mine","et","toi","qui","po-","-sait","nue","la","bo-","-he-","-me","la","bo-","-he-","-me","ca","vou-","-lait","dire","on","est","heu-","-reux","la","bo-","-he-","-me","la","bo-","-he-","-me","nous","ne","man-","-gions","qu'un","jour","sur","deux"]
128
129 #s.lyrics = ["quand","nous","chan-","-te-","-rons","le","temps","des","ce-","-rises","et","gai","ros-","-si-","-gnol","et","mer-","-le","mo-","-queur","se-","-ront","tous","en","fe-","-e-","-te","les","bel-","-les","au-","-ront","la","fo-","-lie","en","te","te","et","les","a-","-mou-","-reux","du","so-","-leil","au","coeur","quand","vous","chan-","-te-","-rez","le","temps","des","ce-","-rises","sif-","-fle-","-ra","bien","mieux","le","mer-","-le","mo-","-queur"]
130
131 #s.lyrics=["il","pleut","il","pleut","ber-","-ge-","-re","ren-","-tre","tes","blancs","mou-","-tons","al-","-lons","a","ma","chau-","-mie-","-re","ber-","-ge-","-re","vite","al-","-lons","j'en-","-tends","sur","le","feu-","-illa-","-ge","l'eau","qui","tombe","a","grand","bruit","voi-","-ci","ve-","-nir","l'o-","-ra-","-a-","-ge","voi-","-ci","l'e-","-clair","qui","luit"]
132
133 #s.lyrics = ["c'est","une","chan-","-son","qui","nous","res-","-sem-","-ble","toi","tu","m'ai-","-mais","et","je","t'ai-","-mais","nous","e-","-tions","tout","les","deux","en-","-sem-","-ble","toi","qui","m'ai-","-mais","moi","qui","t'ai-","-mais","mais","la","vie","se-","-pare","ceux","qui","s'aiment","tout","dou-","-ce-","-ment","sans","faire","de","bruit","et","la","mer","ef-","-fa-","-ce","sur","le","sa-","-ble","les","pas","des","a-","-mants","de-","-su-","-nis"]
134
135 # s.lyrics = ["quand","il","me","prend","dans","ses","bras","qu'il","me","par-","-le","tout","bas","je","vois","la","vie","en","ro-","-se","il","me","dit","des","mots","d'a-","-mour","des","mots","de","tous","les","jours","et","ca","m'fait","quel-","-que","cho-","-se","il","est","en-","-tre","dans","mon","coeur","u-","-ne","part","de","bon-","-heur","dont","je","con-","-nais","la","cau-","-se","c'est","lmui","pour","moi","moi","pour","lui","dans","la","vie","il","m'a","pro-","-mis","m'a","ju-","-re","pour","la","vie","et","des","que","je","l'a-","-per-","-cois","a-","-lors","je","sens","en","moi","mon","coeur","qui","bat"]
136
137 s.save("smwis/boheme.smwi")