Esempio n. 1
0
    def __init__(self,
                 song,
                 songDb,
                 errorNotifyCallback=None,
                 doneCallback=None):
        """The first parameter, song, may be either a pykdb.SongStruct
        instance, or it may be a filename. """

        pykPlayer.__init__(self, song, songDb, errorNotifyCallback,
                           doneCallback)

        self.Movie = None

        manager.setCpuSpeed('mpg')

        manager.InitPlayer(self)
        manager.OpenDisplay(depth=DISPLAY_DEPTH)

        # Close the mixer while using Movie
        manager.CloseAudio()

        # Open the Movie module
        filepath = self.SongDatas[0].GetFilepath()
        if type(filepath) == unicode:
            filepath = filepath.encode(sys.getfilesystemencoding())
        self.Movie = pygame.movie.Movie(filepath)
        self.Movie.set_display(
            manager.display,
            (0, 0, manager.displaySize[0], manager.displaySize[1]))
Esempio n. 2
0
    def errorPopupCallback(self, errorString, wait=True):
        print(errorString)

        manager.InitPlayer(self)
        manager.OpenDisplay()

        manager.display.fill((0, 0, 0))

        # Center the error message onscreen.
        winWidth, winHeight = manager.displaySize
        winCenter = winWidth / 2

        lines = manager.WordWrapText(errorString, self.subtitleFont,
                                     winWidth - X_BORDER * 2)

        row = (winHeight - len(lines) * self.subtitleHeight) / 2
        for line in lines:
            line = line.strip()
            text = self.subtitleFont.render(line, True, (255, 255, 255))
            rect = text.get_rect()
            rect = rect.move(winCenter - rect.centerx, row)
            manager.display.blit(text, rect)
            row += self.subtitleHeight

        pygame.display.flip()
        self.screenDirty = True

        if not wait:
            return

        # Now wait a certain amount of time--say 5 seconds.
        waitUntil = pygame.time.get_ticks() + 5000

        # But also, wait a quarter second to give the user a chance to
        # react and stop hitting buttons.
        pygame.time.wait(250)

        # Discard any events that occurred in that quarter second.
        for event in pygame.event.get():
            pass

        # Now start listening for events.  The first key or button
        # event gets us out of here.
        buttonPressed = False
        while not buttonPressed and pygame.time.get_ticks() < waitUntil:
            for event in pygame.event.get():
                if event.type == pygame.KEYDOWN or \
                   (env == ENV_GP2X and event.type == pygame.JOYBUTTONDOWN):
                    buttonPressed = True
                    break
Esempio n. 3
0
    def __init__(self, song, songDb, errorNotifyCallback=None, doneCallback=None):
        """The first parameter, song, may be either a pykdb.SongStruct
        instance, or it may be a filename. """

        pykPlayer.__init__(self, song, songDb, errorNotifyCallback, doneCallback)

        self.Movie = None

        manager.setCpuSpeed('mpg')
        manager.InitPlayer(self)

        # Close the audio and the display
        manager.CloseAudio()
        manager.CloseDisplay()
        manager.CloseCPUControl()

        self.procReturnCode = None
        self.proc = None
Esempio n. 4
0
    def showProgressCallback(self, label, progress):
        """ This is called by the MiniBusyCancelDialog to show
        progress as we're scanning the database. """

        manager.InitPlayer(self)
        manager.OpenDisplay()

        manager.display.fill((0, 0, 0))

        # Center the error message onscreen.
        winWidth, winHeight = manager.displaySize
        winCenter = winWidth / 2

        lines = manager.WordWrapText(label, self.subtitleFont,
                                     winWidth - X_BORDER * 2)

        row = winHeight / 2 - 2 * self.subtitleHeight
        for line in lines:
            line = line.strip()
            text = self.subtitleFont.render(line, True, (255, 255, 255))
            rect = text.get_rect()
            rect = rect.move(winCenter - rect.centerx, row)
            manager.display.blit(text, rect)
            row += self.subtitleHeight

        # Now draw the progress bar.
        width = winWidth / 2
        height = self.subtitleHeight

        top = winHeight / 2
        left = winWidth / 2 - width / 2
        rect = pygame.Rect(left, top, width, height)
        manager.display.fill((255, 255, 255), rect)

        fill = int((width - 2) * progress + 0.5)
        rect = pygame.Rect(left + 1 + fill, top + 1, width - 2 - fill,
                           height - 2)
        manager.display.fill((0, 0, 0), rect)

        pygame.display.flip()
        self.screenDirty = True
Esempio n. 5
0
    def beginSong(self, file):
        self.selectedSong = None
        manager.setCpuSpeed('load')
        manager.display.fill((0, 0, 0))

        winWidth, winHeight = manager.displaySize
        winCenter = winWidth / 2

        rowA = winHeight / 3
        rowC = winHeight * 5 / 6

        self.__writeSongTitle(file, rowA)

        text = self.subtitleFont.render("Loading", True, (255, 255, 255))
        rect = text.get_rect()
        rect = rect.move(winCenter - rect.centerx, rowC)
        manager.display.blit(text, rect)

        pygame.display.flip()

        # This will call the songFinishedCallback, so call it early.
        self.shutdown()

        self.writeMarkedSongs()

        player = file.MakePlayer(self.songDb, self.errorPopupCallback,
                                 self.songFinishedCallback)
        if player == None:
            return

        # Start playing.
        try:
            player.Play()
        except:
            self.errorPopupCallback("Error starting player.\n%s\n%s" %
                                    (sys.exc_info()[0], sys.exc_info()[1]))
            return

        # Go to sleep until the song is over.
        try:
            manager.WaitForPlayer()
        except:
            self.errorPopupCallback("Error while playing song.\n%s\n%s" %
                                    (sys.exc_info()[0], sys.exc_info()[1]))
            return

        # The song is over.  Now recover control and redisplay the
        # song list.

        manager.OpenCPUControl()
        manager.setCpuSpeed('menu_fast')
        self.heldStartTicks = pygame.time.get_ticks()

        manager.InitPlayer(self)
        manager.OpenDisplay()

        # In case the screen has been resized during the song.
        self.setupScrollWindow()

        self.screenDirty = True

        # Discard any events that occurred while we were resetting the
        # display.
        for event in pygame.event.get():
            pass
Esempio n. 6
0
    def start(self):
        self.appStart = pygame.time.get_ticks()
        self.heldStartTicks = self.appStart
        manager.OpenCPUControl()
        manager.setCpuSpeed('startup')

        self.numSongInfoLines = 1

        self.setupSplashScreen()
        manager.InitPlayer(self)
        self.setupScrollWindow()

        self.screenDirty = True

        needsSave = False

        if manager.options.scan_dir:
            # Replace the old scan list.
            self.songDb.Settings.FolderList = [manager.options.scan_dir]
            needsSave = True

        if manager.options.scan_dirs:
            # Add one or more new directories to the list.
            self.songDb.Settings.FolderList += manager.options.scan_dirs
            needsSave = True

        if manager.options.scan:
            # Re-scan the files.
            self.songDb.BuildSearchDatabase(pykdb.AppYielder(),
                                            MiniBusyCancelDialog(self))
            needsSave = True
        else:
            # Read the existing database.
            self.songDb.LoadDatabase(self.errorPopupCallback)

        if needsSave:
            self.songDb.SaveSettings()
            self.songDb.SaveDatabase()

        if not self.songDb.FullSongList:
            # No files.
            self.errorPopupCallback("No songs in catalog.")
            return

        if manager.options.validate:
            manager.ValidateDatabase(self.songDb)
            return

        if self.songDb.GotTitles:
            self.numSongInfoLines += 1
        if self.songDb.GotArtists:
            self.numSongInfoLines += 1
        self.setupScrollWindow()

        self.readMarkedSongs()

        if self.songDb.GotTitles:
            self.songDb.SelectSort('title')
        elif self.songDb.GotArtists:
            self.songDb.SelectSort('artist')
        else:
            self.songDb.SelectSort('filename')

        self.currentRow = 0
        self.searchString = ''
        self.heldKey = None
        self.heldStartTicks = 0
        self.heldRepeat = 0

        manager.setCpuSpeed('wait')

        # Now that we've finished loading, wait up a second and give
        # the user a chance to view the splash screen, in case we
        # loaded too fast.
        if self.splashStart != None:
            splashTime = pygame.time.get_ticks() - self.splashStart
            remainingTime = 2500 - splashTime
            if remainingTime > 0:
                pygame.time.wait(remainingTime)

        self.running = True

        manager.setCpuSpeed('menu_fast')
        self.heldStartTicks = pygame.time.get_ticks()

        while self.running:
            manager.Poll()

        self.writeMarkedSongs()
        manager.CloseDisplay()
Esempio n. 7
0
    def __init__(self,
                 song,
                 songDb,
                 errorNotifyCallback=None,
                 doneCallback=None):
        """The first parameter, song, may be either a pykdb.SongStruct
        instance, or it may be a filename. """

        pykPlayer.__init__(self, song, songDb, errorNotifyCallback,
                           doneCallback)

        # With the nomusic option no music will be played.
        soundFileData = None
        if not manager.options.nomusic:
            # Check for a matching mp3 or ogg file.  Check extensions
            # in the following order.
            validexts = ['.wav', '.ogg', '.mp3']

            for ext in validexts:
                for data in self.SongDatas:
                    if data.Ext == ext:
                        # Found a match!
                        soundFileData = data
                        break
                if soundFileData:
                    break

            if not soundFileData:
                ErrorString = "There is no mp3 or ogg file to match " + self.Song.DisplayFilename
                self.ErrorNotifyCallback(ErrorString)
                raise 'NoSoundFile'

        self.cdgFileData = self.SongDatas[0]
        self.soundFileData = soundFileData
        self.soundLength = 0

        # Handle a bug in pygame (pre-1.7) which means that the position
        # timer carries on even when the song has been paused.
        self.pauseOffsetTime = 0

        manager.InitPlayer(self)
        manager.OpenDisplay()
        manager.surface.fill((0, 0, 0))

        # A working surface for blitting tiles, one at a time.
        self.workingTile = pygame.Surface((TILE_WIDTH, TILE_HEIGHT), 0,
                                          manager.surface)

        # A surface that contains the set of all tiles as they are to
        # be assembled onscreen.  This surface is kept at the original
        # scale, then zoomed to display size.  It is only used if
        # settings.CdgZoom == 'soft'.
        self.workingSurface = pygame.Surface(
            (CDG_DISPLAY_WIDTH, CDG_DISPLAY_HEIGHT), pygame.HWSURFACE,
            manager.surface)

        self.borderColour = None
        self.computeDisplaySize()

        aux = aux_c
        if not aux or not manager.settings.CdgUseC:
            print("Using Python implementation of CDG interpreter.")
            aux = aux_python

        # Open the cdg and sound files
        self.packetReader = aux.CdgPacketReader(self.cdgFileData.GetData(),
                                                self.workingTile)
        manager.setCpuSpeed('cdg')

        if self.soundFileData:
            # Play the music normally.
            audioProperties = None
            if manager.settings.UseMp3Settings:
                audioProperties = self.getAudioProperties(self.soundFileData)
            if audioProperties == None:
                audioProperties = (None, None, None)
            try:
                manager.OpenAudio(*audioProperties)
                audio_path = self.soundFileData.GetFilepath()
                if type(audio_path) == unicode:
                    audio_path = audio_path.encode(sys.getfilesystemencoding())
                pygame.mixer.music.load(audio_path)
            except:
                self.Close()
                raise

            # Set an event for when the music finishes playing
            pygame.mixer.music.set_endevent(pygame.USEREVENT)

            # Account for the size of the playback buffer in the lyrics
            # display.  Assume that the buffer will be mostly full.  On a
            # slower computer that's struggling to keep up, this may not
            # be the right amount of delay, but it should usually be
            # pretty close.
            self.InternalOffsetTime = -manager.GetAudioBufferMS()

        else:
            # Don't play anything.
            self.InternalOffsetTime = 0

        # Set the CDG file at the beginning
        self.cdgReadPackets = 0
        self.cdgPacketsDue = 0
        self.LastPos = self.curr_pos = 0

        # Some session-wide constants.
        self.ms_per_update = (1000.0 / manager.options.fps)
Esempio n. 8
0
    def __init__(self,
                 song,
                 errorNotifyCallback=None,
                 doneCallback=None,
                 Charset="iso-8859-1"):
        """The first parameter, song, may be either a pykdb.SongStruct
        instance, or it may be a filename. """

        pykPlayer.__init__(self, song, errorNotifyCallback, doneCallback)

        self.SupportsFontZoom = True

        # Parse the MIDI file
        self.midifile = midiParseData(self.SongDatas[0].GetData(),
                                      self.ErrorNotifyCallback, Charset)
        if (self.midifile == None):
            ErrorString = "ERROR: Could not parse the MIDI file"
            self.ErrorNotifyCallback(ErrorString)
            return
        elif (self.midifile.lyrics == None):
            ErrorString = "ERROR: Could not get any lyric data from file"
            self.ErrorNotifyCallback(ErrorString)
            return

        # Debug out the found lyrics
        if debug:
            self.midifile.lyrics.write()

        manager.InitPlayer(self)
        manager.OpenDisplay()

        # Reduce the default sample rate on the GP2x to save CPU time.
        if env == ENV_GP2X:
            manager.OpenAudio(suggestedProperties=(12000, -16, 1))
        else:
            manager.OpenAudio(suggestedProperties=(22050, -16, 2))

        # Account for the size of the playback buffer in the lyrics
        # display.  Assume that the buffer will be mostly full.  On a
        # slower computer that's struggling to keep up, this may not
        # be the right amount of delay, but it should usually be
        # pretty close.
        self.InternalOffsetTime = -manager.GetAudioBufferMS()

        self.screenDirty = False
        self.initFont()

        # Windows reports the song time correctly (including period up
        # to the first note), so no need for the earliest note hack
        # there.  On timidity-based platforms, we anticipate our
        # lyrics display by the time of the first note.
        if env != ENV_WINDOWS:
            self.InternalOffsetTime += self.midifile.earliestNoteMS

        # Now word-wrap the text to fit our window.
        self.lyrics = self.midifile.lyrics.wordWrapLyrics(self.font)

        # By default, we will use the get_pos() functionality returned
        # by pygame to get the current time through the song, to
        # synchronize lyric display with the music.
        self.useMidiTimer = True

        if env == ENV_WINDOWS:
            # Unless we're running on Windows.  For some reason, MIDI
            # playback on Windows reports an unreliable time.  To
            # avoid that problem, we'll always use the CPU timer
            # instead of the MIDI timer.
            self.useMidiTimer = False

        # Load the MIDI player
        if not manager.options.nomusic:
            pygame.mixer.music.load(self.SongDatas[0].GetFilepath())

            # Set an event for when the music finishes playing
            pygame.mixer.music.set_endevent(pygame.USEREVENT)
        else:
            # If we're not playing music, use the CPU timer instead of
            # the MIDI timer.
            self.useMidiTimer = False

        # Reset all the state (current lyric index etc) and
        # paint the first numRows lines.
        self.resetPlayingState()