versiones usar que descargar debo actual python-2.7 time pygame midi

python 2.7 - usar - Problemas de sincronización en Metronome Script en Python(usando Pygame)



que version de python usar (0)

Estoy tratando de crear un guión de metrónomo que me brinde retroalimentación de audio y envíe mensajes MIDI a un sintetizador. Uso Python 2.7.5+ y Pygame 1.9.1.release en Linux Mint 16. Estoy de acuerdo con la parte MIDI. Lo que me preocupa es el tiempo.

En primer lugar, aquí está básicamente lo que hago:

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()

Sin embargo, esto es bastante inestable e imposible de tocar un instrumento para.

También busqué en time.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()

... así como pygame.time.Clock() , específicamente pygame.time.Clock.tick_busy_loop() , que supuestamente proporciona una mayor precisión al comer más en el procesador:

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

Todo lo cual produjo los mismos problemas. Aunque, debo admitir, cuando probé estos ejemplos mínimos, la solución de pygame.time fue muy estable. El problema aquí es que en mi guión actual hago algunos cálculos (como incrementar contadores y enviar mensajes MIDI) dentro del ciclo while que parecen influir en el tiempo que toma el bucle y el clic comienza a tartamudear y tropezar.

Miré esta respuesta , pero no entendí la idea de los archivos midi. ¿Puede eso ayudar aquí? Alguna explicación sería de gran ayuda.

Además, traté de poner

import os os.nice(-19)

al principio, para obtener una mayor prioridad de proceso, pero no se notó ninguna mejora.

Me pregunto cómo puedo lograr un metrónomo estable como DAW comunes como Cubase, Ableton y Logic. Leí sobre el enfoque para generar o pregrabar muestras de audio del tempo en cuestión y encadenar esas muestras para lograr una mayor precisión, pero realmente me gustaría evitar este enfoque, ya que parece muy laborioso.

¿Hay alguna forma inteligente de usar la variante estable de pygame.time y hacer el procesamiento en otro lugar?

Si es de alguna utilidad: aquí está el bucle while actual que estoy ejecutando:

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

El problema es que el estándar MIDI exige 24 mensajes por negra, lo que aumenta significativamente la demanda de precisión.