1

Why doesn't this play my click.wav every 444ms? it just seems to play it at random intervals.

import pygame

pygame.init()
size = (700, 500)
screen = pygame.display.set_mode(size)

pygame.display.set_caption("444ms click")
done = False
clock = pygame.time.Clock()
noise = pygame.mixer.Sound("click.wav")
pygame.time.set_timer(1, 444)

while not done:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
        if event.type == 1:
            noise.play()

    clock.tick(60)

pygame.quit()

and if anyone knows how I could do this more easily that would be good.

Thank You!

@JFSebeastian: Here's the output for the code:

447
436
443
430
449
431
448
432
910
7
407
447
442
432
446
431
448
432
450
432
446
472
jfs
  • 399,953
  • 195
  • 994
  • 1,670

1 Answers1

1

Use event.type == pygame.USEREVENT + 1, otherwise the event may be generated for other reasons (whatever 1 event type corresponds to in pygame) that is why it appears random.


The output for the code shows that the time intervals are mostly 440±10 ms with the exception of 910, 7 pair.

±10 milliseconds for a timer sounds normal for fps=60. To get tighter timings, you could use clock.tick() instead of clock.tick(60).

910, 7 pair suggests that set_timer()/tick() might use a time.sleep() analog somewhere. time.sleep() may sleep more than specified that is why the timer may skip a beat. Try clock.tick_busy_loop() that shouldn't sleep and see if you can reproduce the skips.

jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • Hi JF Sebastian and thanks for your advice. The code now has pygame.USEREVENT + 1 in place of the number 1 where you said and in the set_timer argument and seems slightly better but still not right. The clicks are mostly played in a kind of swing rhythm like this (1 = note, 0 = rest) 110110110110... Why do you think that is!?!? – Tom Edwards Oct 29 '14 at 12:55
  • @TomEdwards: you need to change the `set_timer()` call too (replace `1` with `USEREVENT+1`). [I've tested it and it works fine on my system.](https://gist.github.com/zed/dcc6ae76487add302371) – jfs Oct 29 '14 at 14:55
  • @JFSebeastian: Thanks. I replaced 1 in set_timer() with `pygame.USEREVENT+1` and it was still random. Then I tried it without the 'pygame.' and just wrote `USEREVENT+1` as the first argument, like you said and it gave me the error `NameError: name 'USEREVENT' is not defined` cheers. – Tom Edwards Oct 29 '14 at 15:58
  • @TomEdwards: it must be clear from the context that I meant `pygame.USEREVENT` when I said `USEREVENT`. You should be capable to resolve such issues (`NameError`) yourself. Could you run [the code I've linked above](https://gist.github.com/zed/dcc6ae76487add302371) and post its output in your question? – jfs Oct 29 '14 at 16:00
  • @JFSebeastian: You're right, sorry. I ran the code and printed some of the output in my question as you asked. Still random timings and looks like it, from the output, especially the `910 7`. something wrong with my system maybe? – Tom Edwards Oct 30 '14 at 12:58
  • @TomEdwards: I've added the explanation for the code results and some possible workarounds. – jfs Oct 30 '14 at 13:25
  • @JFSebeastian: Thanks, I changed your code to use `Clock.tick_busy_loop()` and it was a good improvement. The output was consistently 440 but although the click was much more pulse like, it still skips every 2-3 beats. – Tom Edwards Oct 30 '14 at 17:54
  • @TomEdwards: when you say "skips" do you mean the value is significantly larger/smaller (like `910`, `7`)? I run the code that uses `clock.tick()` (note: lowercase `clock`) 4 hours without a pause: it has *not* skipped even once. How many CPU cores do you have? Is your system busy? – jfs Oct 30 '14 at 18:01
  • @JFSebeastian: The value is consistant its the sound only that is skipping, it reminds me of when you loop something on media player, its always choppy not a perfect loop. which makes me think that its just not the best way to achieve what I'm trying to do, I think i just need something more acurate. Maybe however, it will work with images which is my actual motive for doing it so I will try that and see what the results are. I'll post my results once I've worked it out. Is there any other way of syncronising events to a beat? – Tom Edwards Oct 31 '14 at 17:50
  • @TomEdwards: if you need precision bettern than 10s milliseconds, you need to be more specific about your code (showing images may or may not produce a difference compared to playing a sound but it is one less variable to think about). What happens if you try [this code](http://stackoverflow.com/a/26609843/4279) on your system? – jfs Dec 01 '14 at 17:40