Вопрос с питоном, музыкой и событиями, есть ли более элегантный способ программирования? - PullRequest
0 голосов
/ 15 декабря 2018

Цель: Создать программу, которая сможет выключать и включать свет для музыки на основе событий, которые запускаются из миди-нот.

Привет всем, я надеюсь, чтоэто не слишком широкий вопрос, чтобы спросить.Я работаю над проектом, в котором я получаю события из файла midi и превращаю их во время.Я беру заметку из миди-файла и добавляю ее в список по мере того, как она была помещена

Пример: https://imgur.com/swZsrk9

Я беру все из них и помещаю их в список.Не беспокойтесь о том, как я это делаю, потому что это не моя главная цель для обсуждения.Я только что заменил список жестко закодированным в моем примере кода.

Теперь у меня есть список случаев, когда я хочу, чтобы свет включался или выключался, теперь мне просто нужно установить бесконечный цикл с таймером, который начинается с 0 секунд (с началом песни), икогда таймер == (в следующий раз в списке), он напечатает строку.Вот мой код:

import socket
import sys
import random
import time
from pygame import mixer
from mido import MidiFile

masterList = [12.37, 14.37, 15.12, 15.62,16.36, 17.61, 18.11, 19.11, 19.61, 20.35,]
mixer.init()
song = mixer.Sound('song.wav')
startTime = time.time()
endTime = startTime + song.get_length()
print(masterList)
print('Starting song.')
song.play()
print('Playing song, timer:',startTime)
while time.time() <= endTime:
    #print(round(time.clock(),1),masterList[0])
    if round(time.clock(),2) == masterList[0]:
        print(round(time.clock(),2),"<-",masterList[0],"------------------")
        del masterList[0]
    #print('playing...')
    time.sleep(.01)
mixer.quit()

Вот видео о том, как он работает: https://www.youtube.com/watch?v=VW-eNoJH2Wo&feature=youtu.be Игнорировать предупреждения об устаревании

Работает, но иногда из-заПо природе программирования time.clock () не всегда == следующий элемент в списке.Я знал, что это будет проблемой, так как вы не можете рассчитывать на то, сколько времени займет выполнение кода.Иногда для завершения цикла while требуется несколько больше миллисекунд, чем обычно, поэтому при вызове метода time.clock () это! = В следующий раз в списке.Тогда список не удаляет свой первый элемент, и тогда он никогда не будет равен этому первому элементу.

Я пытался идти на 10 миллисекунд (.1), но это не дает мне необходимой точности.

Кроме того, это кажется неуклюжим, иногда события задерживаются на несколько миллисекунд, и этоделает эффект не таким приятным.Как вы можете видеть из моего видео, время отпечатков не выровнено полностью, где они должны быть, даже если они идеально расположены там, где они должны быть в файле midi.

Вопрос: Есть ли более элегантный способ решения этой проблемы?Кажется, я продолжаю находить способы исправления ошибок, чтобы они работали лучше, и тогда это всегда возвращается к природе программирования, где процессор всегда ненадежен.Я пытался придумать разные способы сделать это, но я не могу придумать ни одного.Ваша помощь будет высоко ценится!

1 Ответ

0 голосов
/ 15 декабря 2018

Поскольку вы удаляете ноты во время их воспроизведения, пытались ли вы использовать >= вместо ==?

Например,

while time.time() <= endTime:
    #print(round(time.clock(),1),masterList[0])
    if round(time.clock(),2) >= masterList[0]:
        print(round(time.clock(),2),"<-",masterList[0],"------------------")
        del masterList[0]

Таким образом, нотабудет играть как можно скорее после указанного времени, и удалить его из очереди.Единственный способ узнать реальную производительность - это проверить ее, но, по крайней мере, она не пропустит заметки.

...