2 Created on 15 juil. 2009
4 @author: Samuel Benveniste
14 from numpy
import array
15 from numpy
.linalg
import norm
17 from math
import floor
19 from gui
.constants
import *
20 from PlayingScreen
import PlayingScreen
21 from instruments
.Instrument
import Instrument
22 from cursor
.WarpingCursor
import *
23 from controllers
.Wiimote
import Wiimote
24 from logging
.EventLog
import EventLog
25 from logging
.PickleableEvent
import PickleableEvent
27 joyNames
= ["PPJoy Virtual joystick 1", "PPJoy Virtual joystick 2", "PPJoy Virtual joystick 3"]
28 portNames
= ["Out To MIDI Yoke: 1"]
29 majorScale
= [55, 57, 59, 60, 62, 64, 65, 67, 69, 71, 72]
30 minorScale
= [55, 56, 58, 60, 62, 63, 65, 67, 68, 70, 72]
31 myxolydianScale
= [55, 57, 58, 60, 62, 64, 65, 67, 69, 70, 72]
32 dorianScale
= [55, 57, 58, 60, 62, 63, 65, 67, 69, 70, 72]
33 instrumentImagePathList
= ["piano", "guitare", "accordeon", "violon", "flute", "tuba", "orgue", "violoncelle", "celesta"]
34 octaves
= [0, -1, 0, 1, 1, -2, 0, -1, 0]
38 The screen for choosing instruments
41 The available instruments
43 The wiimotes used in this session
45 The main display window
47 The main display surface
49 The clock used to animate the screen
51 The background that is painted every time
53 The buffer for painting everything before bliting
55 The width of the window in pixels
57 The height of the window in pixels
59 Goes to True when all instruments have been selected
61 The positions of the cursors on the screen, in pixels
63 The rectangles where the images of the instruments are located
65 The numbers of the instruments currently in focus
68 def __init__(self
, instruments
, wiimotes
, window
, screen
, clock
, joys
, portOffset
, eventLog
=None, replay
= False, logFilePath
= None, scaleFactor
= 1, level
= 1):
73 The instruments for this session
75 The wiimotes used in this session
79 self
.scaleFactor
= scaleFactor
81 self
.instruments
= instruments
82 self
.wiimotes
= wiimotes
86 self
.width
= int(floor(screen
.get_width()*self
.scaleFactor
))
87 self
.height
= int(floor(screen
.get_height()*self
.scaleFactor
))
88 self
.blitOrigin
= ((self
.screen
.get_width()-self
.width
)/2,(self
.screen
.get_height()-self
.height
)/2)
90 self
.portOffset
= portOffset
92 self
.currentWiimote
= 0
95 self
.cursorPositions
= []
97 self
.displayedInstruments
= []
98 self
.savedImageRects
= []
103 self
.eventLog
= EventLog()
106 self
.eventLog
= eventLog
109 self
.savedScreen
= pygame
.Surface(self
.screen
.get_size())
111 self
.displayedInstruments
.append(0)
113 self
.displayedInstruments
.append(2)
115 self
.savedScreen
.fill((255, 255, 255))
116 for i
in range(len(self
.displayedInstruments
)):
117 self
.imageRects
.append(self
.drawInstrument(self
.displayedInstruments
[i
]))
119 self
.savedImageRects
= self
.imageRects
[:]
121 #Draw the initial cursor on the buffer
122 self
.playerScreen
= pygame
.Surface(self
.savedScreen
.get_size())
123 self
.playerScreen
.blit(self
.savedScreen
, (0, 0))
125 for i
in range(len(self
.wiimotes
)):
126 #Create the list of instrument focus (one focus per wiimote)
127 self
.focus
.append(None)
128 #Set the screen for the cursors (it can't be set before)
129 self
.wiimotes
[i
].cursor
.screen
= self
.playerScreen
130 self
.cursorPositions
.append(self
.wiimotes
[i
].cursor
.centerPosition
)
132 self
.wiimotes
[self
.currentWiimote
].cursor
.blit(self
.playerScreen
)
135 while self
.done
== False :
137 #Clear the cursors from the screen
138 self
.drawBackground()
139 self
.playerScreen
.blit(self
.savedScreen
, (0, 0))
141 # Limit frame speed to 50 FPS
143 timePassed
= self
.clock
.tick(50)
146 self
.eventLog
.update(timePassed
)
147 pickledEventsToPost
= self
.eventLog
.getPickledEvents()
148 for pickledEvent
in pickledEventsToPost
:
149 pygame
.event
.post(pickledEvent
.event
)
151 events
= pygame
.event
.get()
154 pickledEvents
= [PickleableEvent(event
.type,event
.dict) for event
in events
if self
.eventFilter(event
)]
155 if pickledEvents
!= [] :
156 self
.eventLog
.appendEventGroup(pickledEvents
)
161 for i
in range(len(self
.wiimotes
)):
162 self
.wiimotes
[i
].cursor
.update(timePassed
, self
.cursorPositions
[i
])
164 self
.wiimotes
[self
.currentWiimote
].cursor
.blit(self
.playerScreen
)
166 self
.focus
[self
.currentWiimote
] = None
168 for i
in range(len(self
.imageRects
)) :
169 if self
.imageRects
[i
].collidepoint(self
.cursorPositions
[self
.currentWiimote
]):
170 self
.focus
[self
.currentWiimote
] = i
172 self
.screen
.blit(self
.playerScreen
, (0, 0))
174 pygame
.display
.flip()
176 def input(self
, event
):
177 if event
.type == pygame
.QUIT
:
180 if event
.type == pygame
.JOYAXISMOTION
:
181 self
.updateCursorPositionFromJoy(event
)
182 if event
.type == pygame
.JOYBUTTONDOWN
:
183 self
.joyClicked(event
)
184 if event
.type == pygame
.MOUSEBUTTONDOWN
:
185 self
.mouseClicked(event
)
186 if event
.type == pygame
.MOUSEMOTION
:
187 self
.updateCursorPositionFromMouse(event
)
188 if event
.type == pygame
.KEYDOWN
:
189 if event
.key
== pygame
.K_q
:
192 def updateCursorPositionFromJoy(self
, joyEvent
):
193 joyName
= pygame
.joystick
.Joystick(joyEvent
.joy
).get_name()
194 correctedJoyId
= joyNames
.index(joyName
)
195 if correctedJoyId
< len(self
.cursorPositions
):
196 if joyEvent
.axis
== 0 :
197 self
.cursorPositions
[correctedJoyId
] = (int((joyEvent
.value
+ 1) / 2 * self
.screen
.get_width()), self
.cursorPositions
[correctedJoyId
][1])
198 if joyEvent
.axis
== 1 :
199 self
.cursorPositions
[correctedJoyId
] = (self
.cursorPositions
[correctedJoyId
][0], int((joyEvent
.value
+ 1) / 2 * self
.screen
.get_height()))
201 def assignInstrumentToWiimote(self
, joyEvent
):
202 joyName
= pygame
.joystick
.Joystick(joyEvent
.joy
).get_name()
203 correctedJoyId
= joyNames
.index(joyName
)
204 if self
.zoomed
[correctedJoyId
] == self
.focus
[correctedJoyId
]:
205 self
.wiimotes
[correctedJoyId
].instrument
= self
.instruments
[self
.focus
[correctedJoyId
]]
206 self
.zoomed
[correctedJoyId
] = None
207 self
.imageRects
= self
.savedImageRects
[:]
208 if self
.currentWiimote
<len(self
.wiimotes
)-1:
209 self
.currentWiimote
= self
.currentWiimote
+1
211 self
.zoomed
[correctedJoyId
] = self
.focus
[correctedJoyId
]
212 if self
.hasFinished():
215 def updateCursorPositionFromMouse(self
, mouseEvent
):
216 self
.cursorPositions
[0] = mouseEvent
.pos
218 def assignInstrumentToMouse(self
, mouseEvent
):
219 self
.wiimotes
[0].instrument
= self
.instruments
[self
.focus
[0]]
220 if self
.hasFinished():
223 def hasFinished(self
):
225 for wiimote
in self
.wiimotes
:
226 if wiimote
.instrument
== None:
230 def eventFilter(self
, event
):
234 elif c
== pygame
.MOUSEMOTION
or pygame
.MOUSEBUTTONDOWN
or pygame
.MOUSEBUTTONUP
or pygame
.JOYAXISMOTION
or pygame
.JOYBUTTONDOWN
or pygame
.JOYBUTTONUP
or pygame
.KEYDOWN
:
239 def drawInstrument(self
,instrumentNumber
,drawPos
= None):
241 drawPos
= array([random
.randint(0,self
.width
/2),random
.randint(0,self
.height
/2)])
242 curImage
= pygame
.image
.load(self
.instruments
[instrumentNumber
].image
).convert_alpha()
243 scaledImage
= pygame
.transform
.smoothscale(curImage
, (self
.width
/ 2, self
.height
/ 2))
244 imageRect
= self
.savedScreen
.blit(scaledImage
, drawPos
+ self
.blitOrigin
)
245 pygame
.draw
.rect(self
.savedScreen
, pygame
.Color(0, 0, 0, 255), imageRect
, 5)
248 def drawBackground(self
):
249 self
.savedScreen
.fill((255, 255, 255))
250 for i
in range(len(self
.displayedInstruments
)):
251 self
.drawInstrument(self
.displayedInstruments
[i
], self
.imageRects
[i
].topleft
)
253 pygame
.draw
.rect(self
.savedScreen
, pygame
.Color(0, 255, 0, 255), self
.imageRects
[i
], 10)
255 def mouseClicked(self
,mouseEvent
):
257 self
.wiimotes
[correctedJoyId
].cursor
.flash(400)
258 if self
.focus
[correctedJoyId
] != None :
259 self
.imageRects
.pop(self
.focus
[correctedJoyId
])
260 instrumentNumber
= self
.displayedInstruments
.pop(self
.focus
[correctedJoyId
])
261 self
.drawBackground()
262 self
.imageRects
.append(self
.drawInstrument(instrumentNumber
))
263 self
.displayedInstruments
.append(instrumentNumber
)
264 self
.wiimotes
[correctedJoyId
].instrument
= self
.instruments
[instrumentNumber
]
265 octave
= self
.wiimotes
[correctedJoyId
].instrument
.octave
266 noteOnHexCode
= self
.wiimotes
[correctedJoyId
].getNoteOnHexCode()
267 baseTime
= pygame
.midi
.time()
268 self
.wiimotes
[correctedJoyId
].port
.write([[[noteOnHexCode
,60+12*octave
,127],baseTime
],[[noteOnHexCode
,60+12*octave
,0],baseTime
+500],[[noteOnHexCode
,65+12*octave
,100],baseTime
+510],[[noteOnHexCode
,65+12*octave
,0],baseTime
+1000]])
269 self
.wiimotes
[correctedJoyId
].instrument
= None
271 def joyClicked(self
,joyEvent
):
272 joyName
= pygame
.joystick
.Joystick(joyEvent
.joy
).get_name()
273 correctedJoyId
= joyNames
.index(joyName
)
274 self
.wiimotes
[correctedJoyId
].cursor
.flash(400)
275 if self
.focus
[correctedJoyId
] != None :
276 self
.imageRects
.pop(self
.focus
[correctedJoyId
])
277 instrumentNumber
= self
.displayedInstruments
.pop(self
.focus
[correctedJoyId
])
278 self
.drawBackground()
279 self
.imageRects
.append(self
.drawInstrument(instrumentNumber
))
280 self
.displayedInstruments
.append(instrumentNumber
)
281 self
.wiimotes
[correctedJoyId
].instrument
= self
.instruments
[instrumentNumber
]
282 octave
= self
.wiimotes
[correctedJoyId
].instrument
.octave
283 noteOnHexCode
= self
.wiimotes
[correctedJoyId
].getNoteOnHexCode()
284 baseTime
= pygame
.midi
.time()
285 self
.wiimotes
[correctedJoyId
].port
.write([[[noteOnHexCode
,60+12*octave
,127],baseTime
],[[noteOnHexCode
,60+12*octave
,0],baseTime
+500],[[noteOnHexCode
,65+12*octave
,100],baseTime
+510],[[noteOnHexCode
,65+12*octave
,0],baseTime
+1000]])
286 self
.wiimotes
[correctedJoyId
].instrument
= None
289 def zoomRect(rect
, ratio
):
290 zoomedRect
= rect
.inflate(int(floor((ratio
- 1) * rect
.width
)), int(floor((ratio
- 1) * rect
.height
)))
293 if __name__
== "__main__":
295 #pygame.event.set_blocked([pygame.MOUSEBUTTONDOWN,pygame.MOUSEBUTTONUP,pygame.MOUSEMOTION])
298 instruments
= [Instrument(majorScale
, i
+ 1, "".join(["../instruments/instrumentImages/", instrumentImagePathList
[i
], ".jpg"]), octaves
[i
]) for i
in range(9)]
300 joys
= [pygame
.joystick
.Joystick(id).get_name() for id in range(pygame
.joystick
.get_count())]
301 joyOffset
= joys
.index(joyNames
[0])
302 pygame
.joystick
.Joystick(joyOffset
).init()
305 ports
= [pygame
.midi
.get_device_info(id)[1] for id in range(pygame
.midi
.get_count())]
306 portOffset
= ports
.index(portNames
[0])
309 window
= pygame
.display
.set_mode((1280, 1024),pygame
.FULLSCREEN
)
310 screen
= pygame
.display
.get_surface()
311 clock
= pygame
.time
.Clock()
312 cursorImages
= createImageListFromPath('../cursor/cursorImages/black', 11)
313 durations
= [75 for i
in range(len(cursorImages
))]
318 jadbt
= [3, 4, 5, 3, 4, 4, 5, 6, 6, 5, 3, 3, 4, 5, 3, 4, 4, 5, 6, 7, 3]
321 cursors
= [WarpingCursor(None, cursorImages
, durations
, (300 * i
, 300 * i
),'../cursor/cursorImages/black/flash.png') for i
in range(1)]
322 wiimotes
= [Wiimote(i
, i
+ portOffset
, pygame
.midi
.Output(i
+portOffset
,latency
= 20), None, cursors
[i
]) for i
in range(1)]
323 familiarize
= Familiarizer(instruments
, wiimotes
, window
, screen
, clock
, joyOffset
, portOffset
)
324 for wiimote
in wiimotes
: