2017-04-25 8 views
0

私はAppleのAVMIDIPlayerオブジェクトをMIDIファイルの再生に使用しようとしています。 Swiftでは、次のコードを使用するだけで簡単に見えます。AVMIDIPlayerの再生を維持するには?

let midiFile:NSURL = NSURL(fileURLWithPath:"/path/to/midifile.mid") 
var midiPlayer: AVMIDIPlayer? 

do { 
    try midiPlayer = AVMIDIPlayer(contentsOf: midiFile as URL, soundBankURL: nil) 
    midiPlayer?.prepareToPlay() 
} catch { 
    print("could not create MIDI player") 
} 

midiPlayer?.play { 
    print("finished playing") 
} 

約0.05秒間再生されます。私は何らかのループでフレーム化する必要があると推測します。私は単純な解決策を試みました:

while stillGoing { 
midiPlayer?.play { 
    let stillGoing = false 
} 
} 

これは動作しますが、CPUを大幅に増加させます。より良い方法がありますか? 最初のコメントに加えて、私はクラスを作ろうとしましたが、エラーには何もフラグを立てませんが、どちらも動作しません。

class midiPlayer { 

var player: AVMIDIPlayer? 

    func play(file: String) { 
     let myURL = URL(string: file) 
do { 
    try self.player = AVMIDIPlayer.init(contentsOf: myURL!, soundBankURL: nil) 
    self.player?.prepareToPlay() 
} catch { 
    print("could not create MIDI player") 
} 
    self.player?.play() 
    } 
func stop() { 
self.player?.stop() 
} 
} 

// main 

let myPlayer = midiPlayer() 
let midiFile = "/path/to/midifile.mid" 
myPlayer.play(file: midiFile) 

答えて

1

あなたはループに近づいていました。 midiPlayerがまだ完了しているかどうかを常にチェックするのではなく、CPU時間を与えて他の処理を行うだけです。ループにusleep()への呼び出しを追加します。この1つは第二の10回に1回をチェック:

ブレンダンとスティーブの答えを組み合わせる
let midiFile:NSURL = NSURL(fileURLWithPath:"/Users/steve/Desktop/Untitled.mid") 
var midiPlayer: AVMIDIPlayer? 

do { 
    try midiPlayer = AVMIDIPlayer(contentsOfURL: midiFile, soundBankURL: nil) 
    midiPlayer?.prepareToPlay() 
} catch { 
    print("could not create MIDI player") 
} 

var stillGoing = true 
while stillGoing { 
    midiPlayer?.play { 
     print("finished playing") 
     stillGoing = false 
    } 
    usleep(100000) 
} 
1

あなたはそれが遊んで行われるまでmidiPlayerオブジェクトが存在することを確認する必要があります。上記のコードが単一の関数内にある場合、関数への参照が残っていないため、関数が戻るときにmidiPlayerが破棄されます。通常、サブクラス化されたコントローラのように、オブジェクトのプロパティとしてmidiPlayerを宣言します。

+0

私は関数/メソッドとしてこのコードを持つクラスを作成し、クラスのインスタンスを作成し、メソッドを呼び出す必要がありますか? これまでのところ、これは単なるCLIスクリプトなので、UIコントローラはありません。 – benwiggy

+1

ああ、この場合、ループを使用することは唯一の方法です。 whileループの中に 'sleep(1)'コールを入れて、CPU時間をすべて食べないようにしてください。また、whileループから 'midiPlayer?.play'コールを移動する必要があることは間違いありません。 –

0

、キーはsleepusleepで、CPUをふかし避けるために、ループの外playメソッドを貼り付けます。

player?.play({return}) 
while player!.isPlaying { 
sleep(1) // or usleep(10000) 
} 

stillGoing値は動作しますが、isPlaying方法もあります。

.playは、完了後に永久にぶら下がるのを避けるために、角かっこの間に何か必要です。

多くのありがとうございます。

関連する問題