Функция создания звука беззвучна, когда она назначена на собственный процесс
Я работаю над приложением kivy, которое предназначено для параметрического производства упражнений для тренировки слуха на месте и их воспроизведения. Музыка описывается с помощью модуля Mingus и воспроизводится с помощью его Fluidsynth реализации. У меня есть функция воспроизведения упражнения, которая работает, как и предполагалось, при обычном вызове, но, поскольку с этим методом все остальное зависает во время выполнения упражнения (в бесконечном цикле while, ожидающем остановки вручную), это не приводит к приемлемому поведению. Я назначил функцию ее собственному процессу, используя Process()
и в зависимости от выхода на терминал он зацикливается, как и предполагалось, но звука нет. Еще один момент, заслуживающий внимания, заключается в том, что многократное нажатие на кнопку запуска приводит к тому, что несколько процессов работают параллельно, судя по ритму активности терминала. Вот код Python-интерфейса:
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.recycleview import RecycleView
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.config import Config
from classes import *
from multiprocessing import Process
import yaml
Config.set('graphics', 'width', '400')
Config.set('graphics', 'height', '700')
class Welcome(Screen):
pass
class Builtin(Screen):
pass
class DrillScreen(Screen):
def __init__(self, **kwargs):
super(DrillScreen, self).__init__(**kwargs)
self.options = kwargs['options']
self.desc = self.options.des
self.thedrill = drill(self.options)
desc = Label(
text=self.options.des,
size_hint_x=0.9,
size_hint_y=1)
button = Button(
text = 'Start',
size_hint=[0.4,0.1])
button.bind(on_release=self.startdrill())
self.add_widget(desc)
self.add_widget(button)
def startdrill(self):
def starter(*args):
proc = Process(target=self.thedrill.run)
proc.start()
return starter
class BuiltinView(RecycleView):
def __init__(self, **kwargs):
super(BuiltinView, self).__init__(**kwargs)
with open('builtin.yaml', 'r') as builtin:
self.drills = yaml.load(builtin)
self.data = [ {'text': self.drills[i]['name'],
'on_release': self.startermaker(i,self.drills[i])}
for i in sorted(self.drills.keys()) ]
def startermaker(self,num,options):
def startdrill():
options = drilloptions(self.drills[num])
drillscreen = DrillScreen(name='drill', options=options)
app = App.get_running_app()
app.root.add_widget(drillscreen)
app.root.current = 'drill'
#drillscreen.thedrill.run()
return startdrill
class Manager(ScreenManager):
pass
class TestingApp(App):
def build(self):
return Manager()
TestingApp().run()
drill
класс содержит некоторые параметры в своих атрибутах и входит в цикл для бесконечной генерации упражнений в этих параметрах, когда его .run()
метод называется. в button.bind()
заявление DrillScreen
класс, если я непосредственно положил on_release = self.thedrill.run, я получаю функцию, работающую без проблем. Я не знаю, что мне здесь не хватает. Я могу опубликовать код из других компонентов проекта, если это необходимо. Спасибо.
1 ответ
Ну, пытаясь привести небольшой разбитый пример, я наткнулся на исправление. Я не совсем уверен, почему это работает в одну сторону, а не в другую. Ранее Fluidsynth был инициализирован в .__init__()
метод drill
класс по созданию, я переместил его в .run()
метод. Очень грубо в почти псевдокоде:
До:
class drill:
def __init__(self, opt):
#Some attribute setting
self.ex = None #This will instantiate a class describing a single question
fluidsynth.init(args)
def run(self):
while True:
#Determining randomly the arguments to create Exercise instance
self.ex = Exercise(args)
self.ex.play()
После:
class drill:
def __init__(self, opt):
#Some attribute setting
self.ex = None
def run(self):
fluidsynth.init(args)
while True:
#Determining randomly the arguments to create Exercise instance
self.ex = Exercise(args)
self.ex.play()
Когда я звоню .run()
непосредственно с button.bind()
, обе версии работают. Когда я назначаю его собственному процессу и передаю этот процесс button.bind()
, только вторая версия производит звук. Таким образом, кажется, что примерно происходит то, что инициализированная жидкость не доступна из разных процессов.
Я задержу принятие этого ответа в случае, если кто-то поставит не спекулятивное понимание по этому вопросу.