[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[pygame] Re: BUG:? pygame.mixer.music crash





The crashes persist with 1.8.1release ( downloaded from the pygame link, unistall 1.8.1.rc3, verified  site-packages/pygame disapeared, installed 1.8.1release, run the tests that come with the docs, all passed OK)

A workaround enought good for me:

Instehad of calling directly pygame.mixer.music.play, I stop the music, then wait till pygame.mixer.music is not busy, then wait 0.1 second, finally play the new song. Yeah, clunky, but better than a crash !


Attached are the tests modified to use the workaround; you can look at the code for the details.
Warn: 50 runs with 50 changes take some time.

Also, I noticed that getting sample data files from sourceforge can be inconvenient at present time ( there are migrating datacenter ) so in the short time you can get the files from

 http://rapidshare.com/files/134104315/media_test_claxo.rar.html

The stats where:

**** pygame 1.7.1
using clock.tick(50) - using mode0 ( no wait after unbusy )

initial song: 0
change mode is toggle: 1
time_sleep: 0.5
runs: 50
changes per runs: 50
success: 42
failed: 8


using clock.tick(50) - using mode1 ( wait 0.1 sec after unbusy)

initial song: 0
change mode is toggle: 1
time_sleep: 0.5
runs: 50
changes per runs: 50
success: 50
failed: 0

**** pygame 1.8.1release
clock.tick(50) , using mode0 (no wait after unbusy)

initial song: 0
change mode is toggle: 1
time_sleep: 0.5
runs: 50
changes per runs: 50
success: 50
failed: 0

clock.tick(50) - using mode1 ( wait 0.1 sec after unbusy)

initial song: 0
change mode is toggle: 1
time_sleep: 0.5
runs: 50
changes per runs: 50
success: 50
failed: 0

****
 
@Lenard: glad you are investigating !
 

--
claxo
# begin file mtest2b.py
import pygame
import pygame.mixer
import time


##key1 : togle song
##key2 : reload same song
##key3 : quit
qsong = None
qvol = None
qmusic_state = 0 # 0: not in transition 1: waiting not busy 2: waiting 1 sec delay
qtime = None

def play_music( song, musicVol ):
    global qsong, qvol, qmusic_state
    tmp = pygame.mixer.music.get_busy()
    print 'busy:',tmp,'  ==0?:',tmp==0
    if pygame.mixer.music.get_busy():
        qsong = song
        qvol = musicVol
        qmusic_state = 1
        stop_music()
    else:
        print '*** unbusy ***'
        _play_music( song, musicVol )
        
def _play_music( song, musicVol ):
    print 'About to start song:',song
    pygame.mixer.music.set_volume(musicVol*0.01)
    pygame.mixer.music.load( song )
    pygame.mixer.music.play(-1) # looped

def stop_music():
    if pygame.mixer.get_init():
        pygame.mixer.music.stop()


def play_music_delayed1():  # wait some time after unbusy
    global qmusic_state, qtime
    if not qmusic_state:
        return
    if pygame.mixer.music.get_busy():
        return
    if qmusic_state == 1:
        qtime = time.time()+0.1 # wait 0.1 sec after unbusy
        qmusic_state = 2    
    else:
        if qtime<time.time():
            print '---delayed kicks in the song'
            _play_music(qsong, qvol)
            qmusic_state = 0

def play_music_delayed0():  # play when unbusy
    global qmusic_state
    if not qmusic_state:
        return
    if pygame.mixer.music.get_busy():
        print 'wait...'
        return
    if qmusic_state == 1:
        print '---delayed kicks in the song'
        _play_music(qsong, qvol)
        qmusic_state = 0



pygame.display.init()
pygame.mixer.init(44100, -16, True, 4096)
pygame.mixer.set_num_channels(8)

soundVol = 100
musicVol = 100
songs = ['menu.xm', 'egyptian-trance.xm']
selected = 0

print """
\nUse:
\t t: toggle song
\t r: restart song
\t esc: quit
"""
pygame.display.set_mode((300,300))
screen = pygame.display.get_surface()
screen.fill((0,0,255))
clock = pygame.time.Clock()

print 'pygame.mixer.music.get_busy():',pygame.mixer.music.get_busy()
print 'pygame.mixer.music.get_busy():',pygame.mixer.music.get_busy()
print 'pygame.mixer.music.get_busy():',pygame.mixer.music.get_busy()

bContinue = True
while bContinue:
#    pygame.event.pump()
    for ev in pygame.event.get():
        if (ev.type == pygame.KEYDOWN):
            if ev.key == pygame.K_ESCAPE:
                bContinue = False
            elif ev.key == pygame.K_t:
                selected = not selected
                play_music( songs[selected], musicVol)
            elif ev.key == pygame.K_r:
                play_music( songs[selected], musicVol)
            else:
                pass
    play_music_delayed1()
    pygame.display.update()
    clock.tick(25)
                            
pygame.quit()             
# end file mtest2b.py
#begin file mtest4b.py
import pygame
import pygame.mixer
import sys, time
import subprocess

qsong = None
qvol = None
qmusic_state = 0 # 0: not in transition 1: waiting not busy 2: waiting delay after unbusy
qtime = None

def play_music( song, musicVol ):
    global qsong, qvol, qmusic_state
    tmp = pygame.mixer.music.get_busy()
    print 'busy:',tmp,'  ==0?:',tmp==0
    if pygame.mixer.music.get_busy():
        qsong = song
        qvol = musicVol
        qmusic_state = 1
        stop_music()
    else:
        print '*** unbusy ***'
        _play_music( song, musicVol )
        
def _play_music( song, musicVol ):
    print 'About to start song:',song
    pygame.mixer.music.set_volume(musicVol*0.01)
    pygame.mixer.music.load( song )
    pygame.mixer.music.play(-1) # looped

def stop_music():
    if pygame.mixer.get_init():
        pygame.mixer.music.stop()


def play_music_delayed1():  # wait some time after unbusy
    global qmusic_state, qtime
    if not qmusic_state:
        return
    if pygame.mixer.music.get_busy():
        return
    if qmusic_state == 1:
        qtime = time.time()+0.1 # wait 0.1 sec after unbusy
        qmusic_state = 2    
    else:
        if qtime<time.time():
            print '---delayed kicks in the song'
            _play_music(qsong, qvol)
            qmusic_state = 0

def play_music_delayed0():  # play when unbusy
    global qmusic_state
    if not qmusic_state:
        return
    if pygame.mixer.music.get_busy():
        print 'wait...'
        return
    if qmusic_state == 1:
        print '---delayed kicks in the song'
        _play_music(qsong, qvol)
        qmusic_state = 0

ch_per_run = 0
try:
    ch_per_run = int(sys.argv[1])
    bToggle = int(sys.argv[2])
    selected = int(sys.argv[3])
except:
    pass

if ch_per_run<1:
    print """
    Usage:
    \tmtest3.py  n  b  s  
    Where:
    \tn > 1 Number of changes to try
    \tb = 0-1 1->toggle songs, 0->restart song
    \ts = 0-1 starting song, 0->menu.xm , 1->egyptian-trance.xm 
    """
    sys.exit(1)
    
    

pygame.display.init()
pygame.mixer.init(44100, -16, True, 4096)
pygame.mixer.set_num_channels(8)

soundVol = 100
musicVol = 100
songs = ['menu.xm', 'egyptian-trance.xm']

chtime = time.time()+1.0
play_music( songs[selected], musicVol)
if bToggle:
    selected = not selected

pygame.display.set_mode((300,300))
screen = pygame.display.get_surface()
screen.fill((0,0,255))
clock = pygame.time.Clock()

cntChanges = 0
bContinue = True
while bContinue:
#    pygame.event.pump()
    for ev in pygame.event.get():
        if (ev.type == pygame.KEYDOWN):
            if ev.key == pygame.K_ESCAPE:
                bContinue = False
    if time.time()>chtime:
        chtime = time.time() + 1.0
        play_music( songs[selected], musicVol)
        if bToggle:
            selected = not selected
        cntChanges += 1
        if cntChanges > ch_per_run:
            bContinue = False
    play_music_delayed1()
    pygame.display.update()
    clock.tick(50) # was 25 on 1st series
                            
pygame.quit()             

f = open('tstats.txt','a')
f.write('run completed\n')
f.close()
sys.exit(7)
#end file mtest4b.py
#begin file trunner2b.py
import subprocess, time

# params test run
maxruns = 50
ch_per_run = 50

# 
bToggle = 1
initial_song = 0
time_sleep = 0.5 # use None for no sleep beetwen runs

cntruns = 0
cntfailed = 0

#clean stats
f = open('tstats.txt','w')
f.write('Start.\n')
f.close()

sl = ['python.exe','mtest4b.py','%d'%ch_per_run,'%d'%bToggle,'%d'%initial_song ]
for i in xrange(maxruns):
    cntruns +=1 
    ret = subprocess.call(sl)
    if time_sleep:
        time.sleep(time_sleep)
        
f = open('tstats.txt','r')
cntsucces = len(f.readlines())-1
f.close()
print 'initial song:',initial_song
print 'change mode is toggle:',bToggle
print 'time_sleep:',time_sleep
print 'runs:', maxruns
print 'changes per runs:',ch_per_run
print 'success:',cntsucces
print 'failed:', maxruns-cntsucces
#end file trunner2b.py