2

iOS 5 で CoreAudio を使用して MIDI ファイルを再生しています。再生中にシーケンスを最初からやり直したい場合を除いて、すべてがセットアップされ、機能し、すべてが桃色です。それを行うために、私は自然に次のように呼びます:

    if (MusicPlayerSetTime(musicPlayer, (MusicTimeStamp)0.0) != noErr)
        [NSException raise:@"playMIDI" format:@"Can't reset the player"];

エラーは発生しませんが、この呼び出しを行うと、(ドキュメントに記載されているように) 新しい位置から再生を続けるのではなく、再生が完全に停止します。私もこれを試しました(および同じタイプの他の多くの組み合わせ):

Boolean isPlaying = NO;
if (MusicPlayerIsPlaying(musicPlayer, &isPlaying) != noErr)
    [NSException raise:@"playMIDI:" format:@"Can't get MusicPlayer play state"];

if (isPlaying) {
    if (MusicPlayerStop(musicPlayer) != noErr)
        [NSException raise:@"playMIDI:" format:@"Can't stop MusicPlayer"];
}

if (MusicPlayerSetSequence(musicPlayer, musicSequence) != noErr)
    [NSException raise:@"playMIDI:" format:@"Can't set sequence for MusicPlayer"];

if (MusicPlayerSetTime(musicPlayer, (MusicTimeStamp)0.0) != noErr)
    [NSException raise:@"playMIDI" format:@"Can't reset the player"];

if (MusicPlayerSetPlayRateScalar(musicPlayer, 1.0) != noErr)
    [NSException raise:@"playMIDI" format:@"Can't set speed"];

if (MusicPlayerStart(musicPlayer) != noErr)
    [NSException raise:@"playMIDI" format:@"Can't start MusicPlayer"];

喜びはありません、同じ効果です。

ただし、MusicSequence を変更すると、新しい MusicSequence は正常に再生されます。そのため、同じ MIDI ファイルから 2 つの MusicSequence を作成し、一方から他方に切り替えるという極端な作業を行いました。iOS は、私が同じファイルを 2 回再生したいことを認識しており、それを禁止しています。もう一度再生するには、シーケンスが完全に再生されるまで待つ必要があります。当惑する。

何か案が?

ありがとう

4

2 に答える 2

2

t0 でのシーケンスの開始/停止/再開に問題はありません。シークエンスの音符が、あなたが思っているタイミングであると確信していますか? それとも何か他のことが起こっていますか?

以下のコード (エラー チェックを削除) を使用した簡単なテストでは、問題なく停止し、再起動します。または、あなたが説明した問題を誤解したのかもしれません。Fwiw - stop/start プレーヤー コールがなくても機能しますが、トランジェント ノートがまだ聞こえるため、きれいなジャンプにはなりません。

- (void)jump
{
    if (player) {
        MusicPlayerStop(player)
        MusicPlayerSetTime(player, 0.0f);
        MusicPlayerStart(player);
    }
}

アップデート

.mid ファイルを見て、テストしました。これは、MusicPlayer がファイルを認識する方法です (関数を使用CAShow(nameOfYourSequence))

Sequence @0x68ad7c0
NumTracks = 1, Type = beats
* * TempoTrack * *
SequenceTrack @0x68ab250
    Num Events: 3, Track Length: 0.00 beats
    0.000: Time Sig:4/4, 24 clks/qtr, 8 32nds/clk
    0.000: SMPTE Offset [33:0:0:0.0]
    0.000: Tempo:120.000

* * Track 1 * *
SequenceTrack @0x6a815e0
    Num Events: 9, Track Length: 4.11 beats
    0.000: MetaEvent:03
         0:  30 31 30 31 30 31 31 31                           01010111        
    0.000: MetaEvent:04
         0:  30 31 20 43                                       01 C            
    0.000: MetaEvent:59
         0:  00 00                                             ..              
    0.000: MetaEvent:06
         0:  31 20 4D 41 4A 45 55 52 53                        1 MAJEURS       
    0.000: MetaEvent:06
         0:  31 31                                             11              
    0.000: Note:Ch:0 36 121 (4.113)
    0.000: Note:Ch:0 60 116 (3.931)
    0.000: Note:Ch:0 64 110 (3.931)
    0.000: Note:Ch:0 67 105 (3.931)

そのファイルで問題を再現することができました-以前は見たことがありませんでしたが、作業するファイルは長くなりました。何をしようとしているのかわかりませんが、回避策として、イベントを 0.000 より少し遅れて開始することが考えられます。

一方で、noteOn + noteOff イベントを直接以下を使用して管理することを検討しましたか?

MusicDeviceMIDIEvent (self.samplerUnit, noteCommand, noteNum, onVelocity, 0);
于 2012-06-28T09:40:52.887 に答える
0

わかりました、ここで何が起こっていると思いますか: Core Audio はプルベースです。つまり、ユニットがデータを必要とするとき、そのソースから要求します。ここで、MusicPlayer の時間をリセットすると、t0 などの特定の時間にリセットされます。その直後の時刻 t1 に、この MusicPlayer から供給された AU ノードがデータを要求します。MusicPlayer は t1 を受け取り、一連のイベントのどこに該当するかを計算します。常に t0 よりも大きいため、t0 で正確に開始するイベント (たとえば、MIDI ティック 0 で開始するイベント) は再生されたと見なされ、まったく再生されません。つまり、MIDI ファイルの最初のノートは再生されません。

さて、私のファイルは非常に短く、実際にはティック 0 から始まるコードしか含まれていないため、音符は再生されず、無音になります。

新しいシーケンスをロードしたり、シーケンスがまだ再生されていないときにシーケンスを開始したりすると、なぜこれが起こらないのか、私には明らかではありません...

とにかく、考えられる修正の 1 つは、プレーヤーを停止し、シーケンスを設定し、時間を 0 に設定してから、プレーヤーの開始をたとえば 25 ミリ秒遅らせることです。これは応答性には理想的ではありませんが、機能します。

これを修正するためのもう少し複雑な方法は次のとおりです:
- 音楽プレーヤーが供給しているオーディオ ユニットのレンダリング時にコールバックを設定します (AudioUnitAddRenderNotify())
- シーケンスのリセット時に、時間をリセットしないでくださいプレーヤーにブール値フラグを設定し
ます-レンダリングコールバックで、フラグが設定されている場合、プレーヤーの時間をリセットし、フラグの設定を解除し
ます遅延は発生せず、問題の解釈を検証する傾向があります。

于 2012-06-21T09:03:15.973 に答える