Problemas de tempo no script metrônomo em Python (usando Pygame)

Estou tentando escrever um script de metrônomo que me dê feedback de áudio e envie mensagens MIDI para um sintetizador. eu usoPython 2.7.5+ ePygame 1.9.1.release no Linux Mint 16. Eu estou bem com a parte MIDI. O que me incomoda é o tempo.

Primeiro de tudo, aqui está basicamente o que eu faço:

import time
import pygame.mixer

pygame.mixer.init()
sound = pygame.mixer.Sound('click.wav')

interval = 0.5 #should be equivalent to 120 bpm

t0 = time.time()

while True: #infinite loop, use keyboard interrupt Ctrl-C
    if time.time() - t0 >= interval:
        sound.play()
        t0 = time.time()

No entanto, isso é bastante instável e impossível de tocar um instrumento.

Eu também olheitime.clock():

import time
import pygame.mixer

pygame.mixer.init()
sound = pygame.mixer.Sound('click.wav')

interval = 0.5 #should be equivalent to 120 bpm

t0 = time.clock()

while True:
    if time.clock() - t0 >= interval:
        sound.play()
        t0 = time.clock()

...assim comopygame.time.Clock()especificamentepygame.time.Clock.tick_busy_loop(), que supostamente fornece melhor precisão, consumindo mais no processador:

import pygame.time
import pygame.mixer

pygame.mixer.init()
#pygame.time has no init function

sound = pygame.mixer.Sound('click.wav')
clock = pygame.time.Clock()

interval = 0.5 #should be equivalent to 120 bpm

time_passed = 0
clock.tick_busy_loop()

while True: #infinite loop, use keyboard interrupt Ctrl-C
    time_passed += clock.tick_busy_loop()
    if time_passed >= interval:
        sound.play()
        time_passed = 0

Todos os quais produziram os mesmos problemas. Embora eu tenha que admitir, quando tentei esses exemplos mínimos, opygame.time solução era muito estável. O problema aqui é que, no meu script real, eu faço alguns cálculos (como incrementar contadores e enviar mensagens MIDI) dentro dowhile loop que parece influenciar o tempo que o loop leva e o clique começa a gaguejar e tropeçar.

Eu olheiesta resposta, mas não entendi direito os arquivos midi. Pode ajudar aqui? Alguma explicação seria muito útil.

Além disso, tentei colocar

import os
os.nice(-19)

no início, para obter uma prioridade mais alta do processo, mas nenhuma melhoria foi perceptível.

Eu me pergunto como posso obter um metrônomo estável, como DAWs comuns como Cubase, Ableton e Logic. Eu li sobre a abordagem para gerar ou pré-gravar amostras de áudio do andamento em questão e encadeá-las para obter uma maior precisão, mas eu realmente gostaria de evitar essa abordagem, pois parece muito trabalhosa.

Existe alguma maneira inteligente de usar o estábulopygame.time variante e fazer o processamento em outro lugar?

Se for de alguma utilidade: aqui está owhile loop estou executando:

bpm = 80.0
beats_in_one_second = bpm/60.0
midi_send_interval = beats_in_one_second/24.0 #MIDI convention

playing = True
player.write_short(250) #start
frame_count = 0
quarter_count = 0
time_0 = time.time()

while playing:
    if time.time() - time_0 >= midi_send_interval:
        player.write_short(248) #clock tick
        time_0 = time.time()
        frame_count += 1
        if frame_count == 24:
            sound.play()
            quarter_count += 1
            frame_count = 0
            if quarter_count == 16:
                playing = False

player.write_short(252) #stop

O problema é que o padrão MIDI exige 24 mensagens por semínima, o que aumenta significativamente a demanda por precisão.

questionAnswers(0)

yourAnswerToTheQuestion