-'''\r
-Created on 15 juil. 2009\r
-\r
-@author: Samuel Benveniste\r
-'''\r
-\r
-import pygame\r
-import pygame.midi\r
-import sys\r
-import time\r
-import pickle\r
-import random\r
-\r
-from numpy import array\r
-from numpy.linalg import norm\r
-\r
-from math import floor\r
-\r
-from gui.constants import *\r
-from PlayingScreen import PlayingScreen\r
-from instruments.Instrument import Instrument\r
-from cursor.WarpingCursor import *\r
-from controllers.Wiimote import Wiimote\r
-from logging.EventLog import EventLog\r
-from logging.PickleableEvent import PickleableEvent \r
-\r
-joyNames = ["PPJoy Virtual joystick 1", "PPJoy Virtual joystick 2", "PPJoy Virtual joystick 3"]\r
-portNames = ["Out To MIDI Yoke: 1"]\r
-majorScale = [55, 57, 59, 60, 62, 64, 65, 67, 69, 71, 72]\r
-minorScale = [55, 56, 58, 60, 62, 63, 65, 67, 68, 70, 72]\r
-myxolydianScale = [55, 57, 58, 60, 62, 64, 65, 67, 69, 70, 72]\r
-dorianScale = [55, 57, 58, 60, 62, 63, 65, 67, 69, 70, 72]\r
-instrumentImagePathList = ["piano", "guitare", "accordeon", "violon", "flute", "tuba", "orgue", "violoncelle", "celesta"]\r
-octaves = [0, -1, 0, 1, 1, -2, 0, -1, 0]\r
-\r
-class Familiarizer:\r
- '''\r
- The screen for choosing instruments\r
- \r
- instruments: \r
- The available instruments \r
- wiimotes: \r
- The wiimotes used in this session\r
- window:\r
- The main display window\r
- screen:\r
- The main display surface\r
- clock:\r
- The clock used to animate the screen\r
- savedScreen:\r
- The background that is painted every time\r
- playerScreen:\r
- The buffer for painting everything before bliting\r
- width:\r
- The width of the window in pixels\r
- height:\r
- The height of the window in pixels\r
- done:\r
- Goes to True when all instruments have been selected\r
- cursorPositions:\r
- The positions of the cursors on the screen, in pixels\r
- imageRects:\r
- The rectangles where the images of the instruments are located\r
- focus:\r
- The numbers of the instruments currently in focus\r
- '''\r
- \r
- def __init__(self, instruments, wiimotes, window, screen, clock, joys, portOffset, eventLog=None, replay = False, logFilePath = None, scaleFactor = 1, level = 1):\r
- '''\r
- Constructor\r
- \r
- instruments: \r
- The instruments for this session \r
- wiimotes: \r
- The wiimotes used in this session\r
- '''\r
- \r
- \r
- self.scaleFactor = scaleFactor\r
- \r
- self.instruments = instruments\r
- self.wiimotes = wiimotes\r
- self.window = window\r
- self.screen = screen\r
- self.clock = clock\r
- self.width = int(floor(screen.get_width()*self.scaleFactor))\r
- self.height = int(floor(screen.get_height()*self.scaleFactor))\r
- self.blitOrigin = ((self.screen.get_width()-self.width)/2,(self.screen.get_height()-self.height)/2) \r
- self.joys = joys\r
- self.portOffset = portOffset\r
- \r
- self.currentWiimote = 0\r
- self.done = False \r
- \r
- self.cursorPositions = []\r
- self.imageRects = []\r
- self.displayedInstruments = []\r
- self.savedImageRects = []\r
- self.focus = []\r
- self.level = level\r
- \r
- if eventLog == None:\r
- self.eventLog = EventLog()\r
- self.replay = False\r
- else:\r
- self.eventLog = eventLog\r
- self.replay = replay\r
- \r
- self.savedScreen = pygame.Surface(self.screen.get_size()) \r
- \r
- self.displayedInstruments.append(0)\r
- if level == 1 :\r
- self.displayedInstruments.append(2)\r
- \r
- self.savedScreen.fill((255, 255, 255))\r
- for i in range(len(self.displayedInstruments)):\r
- self.imageRects.append(self.drawInstrument(self.displayedInstruments[i]))\r
- \r
- self.savedImageRects = self.imageRects[:]\r
- \r
- #Draw the initial cursor on the buffer\r
- self.playerScreen = pygame.Surface(self.savedScreen.get_size())\r
- self.playerScreen.blit(self.savedScreen, (0, 0))\r
- \r
- for i in range(len(self.wiimotes)):\r
- #Create the list of instrument focus (one focus per wiimote)\r
- self.focus.append(None)\r
- #Set the screen for the cursors (it can't be set before)\r
- self.wiimotes[i].cursor.screen = self.playerScreen\r
- self.cursorPositions.append(self.wiimotes[i].cursor.centerPosition)\r
- \r
- self.wiimotes[self.currentWiimote].cursor.blit(self.playerScreen)\r
- \r
- #The main loop\r
- while self.done == False :\r
- \r
- #Clear the cursors from the screen\r
- self.drawBackground()\r
- self.playerScreen.blit(self.savedScreen, (0, 0))\r
- \r
- # Limit frame speed to 50 FPS\r
- #\r
- timePassed = self.clock.tick(50)\r
- \r
- if self.replay:\r
- self.eventLog.update(timePassed)\r
- pickledEventsToPost = self.eventLog.getPickledEvents() \r
- for pickledEvent in pickledEventsToPost:\r
- pygame.event.post(pickledEvent.event)\r
- \r
- events = pygame.event.get()\r
- \r
- if not self.replay:\r
- pickledEvents = [PickleableEvent(event.type,event.dict) for event in events if self.eventFilter(event)]\r
- if pickledEvents != [] :\r
- self.eventLog.appendEventGroup(pickledEvents)\r
- \r
- for event in events:\r
- self.input(event)\r
- \r
- for i in range(len(self.wiimotes)):\r
- self.wiimotes[i].cursor.update(timePassed, self.cursorPositions[i])\r
- \r
- self.wiimotes[self.currentWiimote].cursor.blit(self.playerScreen) \r
- \r
- self.focus[self.currentWiimote] = None\r
- \r
- for i in range(len(self.imageRects)) :\r
- if self.imageRects[i].collidepoint(self.cursorPositions[self.currentWiimote]):\r
- self.focus[self.currentWiimote] = i\r
- \r
- self.screen.blit(self.playerScreen, (0, 0))\r
- \r
- pygame.display.flip()\r
- \r
- def input(self, event):\r
- if event.type == pygame.QUIT:\r
- pygame.midi.quit()\r
- sys.exit()\r
- if event.type == pygame.JOYAXISMOTION:\r
- self.updateCursorPositionFromJoy(event)\r
- if event.type == pygame.JOYBUTTONDOWN :\r
- self.joyClicked(event)\r
- if event.type == pygame.MOUSEBUTTONDOWN:\r
- self.mouseClicked(event)\r
- if event.type == pygame.MOUSEMOTION:\r
- self.updateCursorPositionFromMouse(event)\r
- if event.type == pygame.KEYDOWN:\r
- if event.key == pygame.K_q:\r
- self.done = True \r
- \r
- def updateCursorPositionFromJoy(self, joyEvent):\r
- joyName = pygame.joystick.Joystick(joyEvent.joy).get_name()\r
- correctedJoyId = joyNames.index(joyName) \r
- if correctedJoyId < len(self.cursorPositions):\r
- if joyEvent.axis == 0 :\r
- self.cursorPositions[correctedJoyId] = (int((joyEvent.value + 1) / 2 * self.screen.get_width()), self.cursorPositions[correctedJoyId][1])\r
- if joyEvent.axis == 1 :\r
- self.cursorPositions[correctedJoyId] = (self.cursorPositions[correctedJoyId][0], int((joyEvent.value + 1) / 2 * self.screen.get_height())) \r
- \r
- def assignInstrumentToWiimote(self, joyEvent):\r
- joyName = pygame.joystick.Joystick(joyEvent.joy).get_name()\r
- correctedJoyId = joyNames.index(joyName)\r
- if self.zoomed[correctedJoyId] == self.focus[correctedJoyId]:\r
- self.wiimotes[correctedJoyId].instrument = self.instruments[self.focus[correctedJoyId]]\r
- self.zoomed[correctedJoyId] = None\r
- self.imageRects = self.savedImageRects[:]\r
- if self.currentWiimote<len(self.wiimotes)-1:\r
- self.currentWiimote = self.currentWiimote+1\r
- else:\r
- self.zoomed[correctedJoyId] = self.focus[correctedJoyId]\r
- if self.hasFinished():\r
- self.done = True\r
- \r
- def updateCursorPositionFromMouse(self, mouseEvent):\r
- self.cursorPositions[0] = mouseEvent.pos\r
- \r
- def assignInstrumentToMouse(self, mouseEvent):\r
- self.wiimotes[0].instrument = self.instruments[self.focus[0]]\r
- if self.hasFinished():\r
- self.done = True\r
- \r
- def hasFinished(self):\r
- finished = True\r
- for wiimote in self.wiimotes:\r
- if wiimote.instrument == None:\r
- finished = False\r
- return(finished)\r
- \r
- def eventFilter(self, event):\r
- c = event.type\r
- if c == 17:\r
- return False\r
- elif c == pygame.MOUSEMOTION or pygame.MOUSEBUTTONDOWN or pygame.MOUSEBUTTONUP or pygame.JOYAXISMOTION or pygame.JOYBUTTONDOWN or pygame.JOYBUTTONUP or pygame.KEYDOWN:\r
- return True\r
- else:\r
- return False\r
- \r
- def drawInstrument(self,instrumentNumber,drawPos = None):\r
- if not drawPos :\r
- drawPos = array([random.randint(0,self.width/2),random.randint(0,self.height/2)])\r
- curImage = pygame.image.load(self.instruments[instrumentNumber].image).convert_alpha()\r
- scaledImage = pygame.transform.smoothscale(curImage, (self.width / 2, self.height / 2))\r
- imageRect = self.savedScreen.blit(scaledImage, drawPos + self.blitOrigin)\r
- pygame.draw.rect(self.savedScreen, pygame.Color(0, 0, 0, 255), imageRect, 5)\r
- return imageRect \r
- \r
- def drawBackground(self):\r
- self.savedScreen.fill((255, 255, 255))\r
- for i in range(len(self.displayedInstruments)):\r
- self.drawInstrument(self.displayedInstruments[i], self.imageRects[i].topleft)\r
- if i in self.focus:\r
- pygame.draw.rect(self.savedScreen, pygame.Color(0, 255, 0, 255), self.imageRects[i], 10)\r
- \r
- def mouseClicked(self,mouseEvent):\r
- correctedJoyId = 0\r
- self.wiimotes[correctedJoyId].cursor.flash(400)\r
- if self.focus[correctedJoyId] != None :\r
- self.imageRects.pop(self.focus[correctedJoyId])\r
- instrumentNumber = self.displayedInstruments.pop(self.focus[correctedJoyId])\r
- self.drawBackground()\r
- self.imageRects.append(self.drawInstrument(instrumentNumber))\r
- self.displayedInstruments.append(instrumentNumber)\r
- self.wiimotes[correctedJoyId].instrument = self.instruments[instrumentNumber]\r
- octave = self.wiimotes[correctedJoyId].instrument.octave\r
- noteOnHexCode = self.wiimotes[correctedJoyId].getNoteOnHexCode()\r
- baseTime = pygame.midi.time()\r
- 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]])\r
- self.wiimotes[correctedJoyId].instrument = None\r
- \r
- def joyClicked(self,joyEvent):\r
- joyName = pygame.joystick.Joystick(joyEvent.joy).get_name()\r
- correctedJoyId = joyNames.index(joyName)\r
- self.wiimotes[correctedJoyId].cursor.flash(400)\r
- if self.focus[correctedJoyId] != None :\r
- self.imageRects.pop(self.focus[correctedJoyId])\r
- instrumentNumber = self.displayedInstruments.pop(self.focus[correctedJoyId])\r
- self.drawBackground()\r
- self.imageRects.append(self.drawInstrument(instrumentNumber))\r
- self.displayedInstruments.append(instrumentNumber)\r
- self.wiimotes[correctedJoyId].instrument = self.instruments[instrumentNumber]\r
- octave = self.wiimotes[correctedJoyId].instrument.octave\r
- noteOnHexCode = self.wiimotes[correctedJoyId].getNoteOnHexCode()\r
- baseTime = pygame.midi.time()\r
- 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]])\r
- self.wiimotes[correctedJoyId].instrument = None\r
- \r
-\r
-def zoomRect(rect, ratio):\r
- zoomedRect = rect.inflate(int(floor((ratio - 1) * rect.width)), int(floor((ratio - 1) * rect.height)))\r
- return(zoomedRect) \r
-\r
-if __name__ == "__main__":\r
- pygame.init()\r
- #pygame.event.set_blocked([pygame.MOUSEBUTTONDOWN,pygame.MOUSEBUTTONUP,pygame.MOUSEMOTION])\r
- \r
- pygame.midi.init()\r
- instruments = [Instrument(majorScale, i + 1, "".join(["../instruments/instrumentImages/", instrumentImagePathList[i], ".jpg"]), octaves[i]) for i in range(9)]\r
- \r
- joys = [pygame.joystick.Joystick(id).get_name() for id in range(pygame.joystick.get_count())]\r
- joyOffset = joys.index(joyNames[0])\r
- pygame.joystick.Joystick(joyOffset).init()\r
- print(joyOffset) \r
- \r
- ports = [pygame.midi.get_device_info(id)[1] for id in range(pygame.midi.get_count())]\r
- portOffset = ports.index(portNames[0])\r
- print(portOffset)\r
- \r
- window = pygame.display.set_mode((1280, 1024),pygame.FULLSCREEN)\r
- screen = pygame.display.get_surface()\r
- clock = pygame.time.Clock() \r
- cursorImages = createImageListFromPath('../cursor/cursorImages/black', 11)\r
- durations = [75 for i in range(len(cursorImages))]\r
- \r
- extsc = False\r
- casc = False\r
- \r
- jadbt = [3, 4, 5, 3, 4, 4, 5, 6, 6, 5, 3, 3, 4, 5, 3, 4, 4, 5, 6, 7, 3]\r
- song = None\r
- \r
- cursors = [WarpingCursor(None, cursorImages, durations, (300 * i, 300 * i),'../cursor/cursorImages/black/flash.png') for i in range(1)]\r
- wiimotes = [Wiimote(i, i + portOffset, pygame.midi.Output(i+portOffset,latency = 20), None, cursors[i]) for i in range(1)]\r
- familiarize = Familiarizer(instruments, wiimotes, window, screen, clock, joyOffset, portOffset)\r
- for wiimote in wiimotes:\r
- del wiimote.port \r
- \r
- pygame.midi.quit()\r
- sys.exit()\r