Я не могу получить точность, необходимую для метронома.
Здравствуйте,
Я новичок в программировании на Python, хотя у меня есть некоторый опыт работы с Fortran и Matlab.
Я хочу создать основной метроном с Python в качестве моего первого проекта.
Во-первых, я использовал модули time и winsound. Модуль времени использовался для расчета времени ожидания между звуковыми сигналами, которые воспроизводил модуль winsound.
Когда я запускал код и сравнивал его звуковой сигнал с приложением метронома, я понял, что временные интервалы между звуковыми сигналами не были точными. Поэтому я перешел с time.sleep () на asyncio.sleep. На первый взгляд это решило проблему. Поэтому в следующий раз мне пришлось поменять модуль winsound, так как я подумал, что он тоже не точный. Я инициализировал pygame.mixer и импортировал некоторые звуковые файлы wav. И это то, чем я сейчас являюсь.
Является ли проблема pygame.mixer? Есть ли вероятность, что проблема в файлах wav?
Вот код:
# Import Pygame for sound playback. Contextlib is used to avoid pygame's welcoming message.
import contextlib
with contextlib.redirect_stdout(None):
import pygame
# Used asyncio instead of time. Asyncio's sleep funcion is precise where time's sleep function is not.
import asyncio
# Pygame mixer initialize for sound playback.
pygame.mixer.init()
tick1= pygame.mixer.Sound("Metro 1.wav")
tick2= pygame.mixer.Sound("Metro 2.wav")
tick3= pygame.mixer.Sound("Metro 3.wav")
# Basic Metronome script. Bpm is the Beats per minute (Tempo), bpb is the beats per bar (4/4=4, 5/4=5, 7/8=7 etc.)
# and tsound is a variable for the type of tick you want to use in its beat.
async def metro_tic(bpm ,bpb,tsound):
t=0 #
sleep =(60.0 / bpm) # Converting Bpm to miliseconds.
counter = 0 # Counter is a variable that indicates at which beat of the bar the metronome is functioning.
while True:
if counter>=bpb: # If the variable counter is bigger or equal (both bpb and counter are integers so
counter=counter-bpb # only the equal relation counts) than the beats per bar it restarts to the value 0.
else:
if counter % bpb==0: # If counter is equal to 0 (meaning we are at the first beat of the bar)
print('1st Tick') # a unique event occurs (not specified yet!!!).
if tsound[counter]==1: # If tsound eg at the second beat (tsound[2]) is equal to 1,
tick1.play() # number 1 tick sound will play.
elif tsound[counter]==2: # If tsound eg at the second beat (tsound[2]) is equal to 2,
tick2.play() # number 2 tick sound will play.
elif tsound[counter]==3: # If tsound eg at the second beat (tsound[2]) is equal to 3,
tick3.play() # number 3 tick sound will play.
elif tsound[counter]==0: # If tsound eg at the second beat (tsound[2]) is equal to 0,
print ('no tick') # no tick sound will play.
counter += 1 # After each beat counter adds 1 to it's self so as to continue to the next beat
await asyncio.sleep(sleep) # Metro_tic function sleeps for the amount of time calculated at sleep
asyncio.run(metro_tic(80, 4, [1, 2, 2, 2]))