2017-06-05 8 views
0

私は、パラメトリックに耳のトレーニングを演奏して演奏するためのkivyアプリを開発中です。音楽はmingusモジュールを使用して記述され、fluidsynthの実装を通じて再生されます。私は普通に呼び出されたときに意図したとおりに動作するエクササイズ演奏を持っていますが、ドリルが実行されている間はそのメソッドがハングしています(無限ループが手動で停止するのを待っています)。私は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を置くと、問題なく動作する関数が得られます。私はここで何が欠けているのか分からない。必要に応じて、プロジェクトの他のコンポーネントからコードを投稿することができます。ありがとうございました。

+0

私は非常にお手伝いしますが、あなたの問題を100行以下の実行可能コードに分割してみてください。それで、私はそれを私のIDEでコピー・ペーストして実行し、すぐにそれを実行することができるということです。 –

+0

ありがとうございます。私が書いた例は、私が望むように働くことが判明しました。そこでは、簡潔にするために、固定された音楽エンティティでfluidsynthの再生機能を呼び出しました。私はバインドされた関数が引数として渡されるものについて何らかの理解が不足していると思います。例えば、私は把握できない方法で 'Button'インスタンスを渡すことに惨めな回避策として' star arg() 'の定義に' * args'を置きます。 'drill'クラスの' .run() 'メソッドは多くの属性に依存しています。もし' self'が何らかの形で混ざり合うと、それは壊れるかもしれません。私はまだ小さくて壊れた例を書こうとします。 – kuoytfouy

+0

はい、あなたは正しい経路にあります - これは問題の特定に役立ちます。あなたはあなたの答えを編集して、問題が100%の確実性でX行にあると言うことができます。 –

答えて

0

小さな壊れた例を作りようとすると、私はつまずいた。私は本当になぜそれが一方通行ではなく、他の方法で動作しているのか分からない。以前はfluidthynthがdrillクラスの.__init__()メソッドで初期化されましたが、私は.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() 

私はbutton.bind()と直接.run()を呼び出すと、両方のバージョンで動作します。私はそれを独自のプロセスに割り当て、そのプロセスをbutton.bind()に渡すと、2番目のバージョンだけがサウンドを生成します。したがって、おおよそ何が起こっているのかは、初期化されたfluidsynthが異なるプロセスからアクセス可能でないということです。

誰かがこの問題について非投機的な理解を提供する場合に、この回答を受け入れるのを延期します。

+0

ループの前に*を置いてみましたか?複数の初期設定がここで役割を果たすことがありますが、タイミングの問題かもしれません。 – Tshirtman

+0

@Tshirtmanはい、結局のところ私がやっていることです。私はここにそのスケッチをタイプしながらそれを置きました(実際のコードには無関係なものがたくさんあります)。編集、ありがとう。 – kuoytfouy

関連する問題