Fugazi1978
Posts: 21
Joined: Sun Jul 01, 2012 11:43 am

ogg files playing slowly in pygame...

Wed Jul 04, 2012 2:49 pm

Here's the code for my ogg media player with keystroke detection, unfortunately it plays slowly (anyone any ideas?) (can't get pygame to play mp3s):

Code: Select all

import os
import sys
import pygame
import curses
#pygame.init()
loop = 0
esc = 0
os.system('clear')

# music files (ogg) must be in a folder, 'music', in same folder as program
os.system('ls -1pR music > files.out')

# open list of files
f = open('files.out', 'r')

# create a list C[ ]
C = ['this','is','a','list']

# empty c
C[:] = []

# read first line of files.out
A = f.readline()

# reads all lines of files.out, places full path to each file in C[ ]
while esc == 0:
	if A[-2:-1] == ":":
		while loop == 0:
			B = f.readline()
			if B[-2:-1] == ":":
				A = B
			if B[-5:-1] == ".ogg":
				C[len(C)+1:] = [A[:-2] + '/' + B[:-1]]
			if B == "":
				esc = 1
				loop = 1
	else:
		A = f.readline()

#init the curses screen
stdscr = curses.initscr()

#use cbreak to not require a return key press
curses.cbreak()

track = 0
breaker = 0

# set up the mixer
freq = 44100     # audio CD quality
bitsize = -16    # unsigned 16 bit
channels = 2     # 1 is mono, 2 is stereo
buffer = 2048    # number of samples (experiment to get right sound)
pygame.mixer.init(freq, bitsize, channels, buffer)

# optional volume 0 to 1.0
pygame.mixer.music.set_volume(1.0)

# starts pygame clock
clock = pygame.time.Clock()

while breaker == 0:
	pygame.mixer.music.load(C[track])
	pygame.mixer.music.play()
	pz = 1
	# check if playback has finished
	while pygame.mixer.music.get_busy():
		clock.tick(30)
		# python curses to 'get' keyboard input
		k = stdscr.getch()
		# press b to pause/play track
		if curses.keyname(k)=="b":
			if pz == 1:
				pygame.mixer.music.pause()
				pz = 2
			else:
				pygame.mixer.music.play()
				pz = 1
		# press n to move to next track
		if curses.keyname(k)=="n":
			pygame.mixer.music.stop()
		# press v to go back a track
		if curses.keyname(k)=="v":
			track = track -2
			pygame.mixer.music.stop()
		# press q to quit
		if curses.keyname(k)=="q":
			pygame.mixer.quit()
			breaker = 1
			curses.endwin()
	track = track + 1

	# check track number isn't less than first track
	if track < 0:
		track = len(C) + track

	# check track number isn't more than last track
	if track > len(C) - 1:
		track = 0
It plays ogg files, anywhere from within the 'music' folder that is in the same folder as the program.

Any improvements to the current script greatly appreciated. Requires pygame.

Aim of the program is a command line jukebox with keystroke detection for moving through tracks.

Matthew

tcstyle
Posts: 10
Joined: Mon Jul 02, 2012 6:47 pm
Location: Hannover, Germany
Contact: Website

Re: ogg files playing slowly in pygame...

Wed Jul 04, 2012 8:15 pm

Haven't tried your code out yet, but executing pygame.music.play() repeatedly in the mainloop could cause the problem. You should probably execute it only when something like "next track" is happening.

Playing .ogg with pygame.music works fine on the Pi in my game: http://www.raspberrypi.org/phpBB3/viewt ... 32&t=10064
It's started outside the game loop and play() is only executed again if the track stops via an event.

Fugazi1978
Posts: 21
Joined: Sun Jul 01, 2012 11:43 am

Re: ogg files playing slowly in pygame...

Wed Jul 04, 2012 9:09 pm

The pygame.mixer.music.play() is outside the keystroke loop so it plays then enters the keystroke loop until the track ends.

tcstyle
Posts: 10
Joined: Mon Jul 02, 2012 6:47 pm
Location: Hannover, Germany
Contact: Website

Re: ogg files playing slowly in pygame...

Thu Jul 05, 2012 6:01 am

After some sleep and looking at it again: Yeah, you're right. :oops: So that should not be the cause of the issue.
Nevertheless it's kinda strange becuase a very similar concept of playing the music works fine in my code with pygame. After starting to play, there is a loop with some quite heavy processor load for the Pi which doesn't slow the playback.
Maybe something with how curses handles the events slows it down.

Fugazi1978
Posts: 21
Joined: Sun Jul 01, 2012 11:43 am

Re: ogg files playing slowly in pygame...

Thu Jul 05, 2012 8:22 am

I've noticed the ones that sound slow were mp3s of 48000Hz so the oggs are too; I shall put a sample rate detector in and report back.

Fugazi1978
Posts: 21
Joined: Sun Jul 01, 2012 11:43 am

Re: ogg files playing slowly in pygame...

Thu Jul 05, 2012 10:17 am

It works. I shall post the program to be poked and probed.

aspro648
Posts: 2
Joined: Tue Sep 11, 2012 9:26 pm
Location: Corvallis Oregon USA
Contact: Website

Re: ogg files playing slowly in pygame...

Tue Sep 11, 2012 9:36 pm

I was struggling to do something similar (command line audio). Your code did the trick. Here is what I ended up with:

Code: Select all

import os
import sys
import pygame
import curses

MUSIC_PATH = './music' # folder where .ogg files are

def print_help():
    ''' Print keymappings. '''
    stdscr.addstr('b - pause\n')
    stdscr.addstr('n - next\n')
    stdscr.addstr('v - back\n')
    stdscr.addstr('q - quit\n')
    stdscr.addstr('h - help\n')


def get_music(path):
    ''' Return sorted list of .ogg filenames in path. '''
    raw_filenames = os.listdir(path)
    music_files = []
    for filename in raw_filenames:
       if filename.endswith('.ogg'):
          music_files.append(os.path.join(path, filename))
    if len(music_files) == 0:
       print 'Unable to find .oog files in "%s"' % path
       sys.exit()
    return sorted(music_files)


# get list of audio files
music_filenames = get_music(MUSIC_PATH)

# init the curses screen and print info
stdscr = curses.initscr()
curses.noecho() # don't print keys to screen
curses.cbreak()   # use cbreak, does not require [Enter]
curses.curs_set(0) # turn off curser
print_help()

track = 0
paused = False

# set up the mixer
freq = 44100     # audio CD quality
bitsize = -16    # unsigned 16 bit
channels = 1     # 1 is mono, 2 is stereo
buffer = 1024    # number of samples (experiment to get right sound)
pygame.mixer.init(freq, bitsize, channels, buffer)
pygame.mixer.music.set_volume(0.7) # optional volume 0 to 1.0


while True:
    pygame.mixer.music.load(music_filenames[track])
    pygame.mixer.music.play(0, 0)
    stdscr.addstr('playing "%s"\n' % music_filenames[track])
    position = 0
    # loop while current track not finished
    while pygame.mixer.music.get_busy():
        pygame.time.wait(100) #slow loop down

        # python curses to 'get' keyboard input
        event = stdscr.getch()
        if event == ord("b"): # pause
            if not paused:
                paused = True
                pygame.mixer.music.pause()
                stdscr.addstr('paused.\n')
            else:
                paused = False
                pygame.mixer.music.unpause()
                stdscr.addstr('playing "%s"\n' % music_filenames[track])
        if event == ord("n"): # next
            pygame.mixer.music.stop()
        if event == ord("v"): # back
            track = track -2
            pygame.mixer.music.stop()
        if event == ord("q"): # quit
            pygame.mixer.music.stop()
            curses.nocbreak()
            curses.echo()
            curses.endwin()
            pygame.mixer.quit()
            os.system('reset')
            sys.exit()
        if event == ord("h"):
            print_help()

        stdscr.refresh()

    # increment track number         
    track = track + 1
    if track < 0:
        track = len(music_filenames) + track
    if track > len(music_filenames) - 1:
        track = 0


Return to “Python”