Остановите чтение заметок, созданных с помощью fluidsynth, с помощью кнопки в tkinter - PullRequest
0 голосов
/ 03 января 2019

Я нахожусь на python2-7. Я хочу получить в tkinter кнопку, которая останавливает чтение заметок, созданных с помощью fluidsynth.

Я обнаружил, что общим решением является использование time.after как здесь: Как создать кнопку остановки Tkinter GUI, чтобы разорвать бесконечный цикл?

Но в моем случае я не могу использовать ее, потому что мне нужно некоторое время между noteon и noteoff, чтобы датьПродолжительность моих заметок.Более того, я хочу воспроизводить ноты ТОЛЬКО если я нажму на начало (а не в начале, как в решении по ссылке).

Итак, я создал этот код, но он не работает, потому что var_start всегда инициализируется какint:

from tkinter import*
import fluidsynth
import time

fs=fluidsynth.Synth()
fs.start(driver='alsa', midi_driver='alsa_seq')
org_charge = fs.sfload("organ.sf2")
fs.program_select(0,org_charge, 0, 0)
time.sleep(1)

var_start=int

def start():
    global var_start
    var_start=1

def stop():
    global var_start
    var_start=0

root=Tk()

if var_start==1:
    fs.noteon(0,67,127)
    time.sleep(1)
    fs.noteoff(0,67)
    fs.noteon(0,71,127)
    time.sleep(1)
    fs.noteoff(0,71)
    fs.noteon(0,74,127)
    time.sleep(1)
    fs.noteoff(0,74)

Button(root, text='start', command= start).pack(padx=10, pady=10)    
Button(root, text='stop', command= stop).pack(padx=10, pady=10)    

root.mainloop()

У меня нет другой идеи изменить мой код ... Может кто-нибудь мне помочь?

Спасибо

1 Ответ

0 голосов
/ 03 января 2019

Вы инициировали var_start в int в операторе var_start=int, поэтому блок кода в if var_start==1: никогда не будет выполнен. А ваша start() функция просто меняет var_start на 1 и никогда не начинает играть ноты, поэтому ничего не произойдет.

Никогда не вызывайте time.sleep() в основном потоке, так как это заблокирует основной цикл tkinter. Вы можете использовать .after(...) для имитации цикла воспроизведения, а ниже приведен пример кода:

playing = False

def play_notes(notes, index, noteoff):
    global playing
    if noteoff:
        fs.noteoff(0, notes[index])
        index += 1      # next note
    if playing and index < len(notes):
        fs.noteon(0, notes[index], 127)
        # call noteoff one second later
        root.after(1000, play_notes, notes, index, True)
    else:
        # either stopped or no more note to play
        playing = False
        print('done playing')

def start_playing():
    global playing
    if not playing:
        print('start playing')
        playing = True
        notes = [67, 71, 74, 88, 80, 91]
        play_notes(notes, 0, False)
    else:
        print('already playing')

def stop_playing():
    global playing
    if playing:
        playing = False
        print('stop playing')
    else:
        print('nothing playing')

Button(root, text='Start', command=start_playing).pack(padx=10, pady=10)
Button(root, text='Stop', command=stop_playing).pack(padx=10, pady=10)

Это просто пример, который вы можете изменить в соответствии со своими потребностями.

...