3

ユーザー入力と同期して MIDI ファイルを再生できる音楽アプリを作成しようとしています。カスタム ビューを作成し、サウンドを再生し、MIDI データを読み取ることまでできました。ビューの onDraw() メソッドで MIDI データの再生を実行して、ユーザー入力を適用できるようにします。ノート データは、開始からミリ秒単位で測定されたノート ピッチと再生時間の配列として格納されます。

テスト データは、500 ミリ秒 (0.5 秒) ごとに異なるピッチのノートを再生します。各ノートの時間間隔とともに currentThreadTimeMillis() をログに記録しましたが、期待どおりです。小さな変化を伴う 500 ティックごとに、ノートが再生されます。ただし、ミリ秒単位のこのカウントは実際の速度の約半分であり、500 ミリ秒をカウントするのに 1 秒かかります! 私は Galaxy Ace で実行しているので、これは遅いエミュレーターの問題ではありません。

SystemClock.currentThreadTimeMillis() が 1000 ミリ秒をカウントするのに 2 秒かかっているのはなぜですか?

    public void onDraw(Canvas canvas) {
        // TODO : Draw notes
       canvas.drawColor(Color.BLACK);
       canvas.drawBitmap(aNote.img, aNote.x, aNote.y, null);
       if (ready>0){
            elapsed_time = SystemClock.currentThreadTimeMillis() - start_time;
            midi_note_data = MIDI.track_data.get(current_note);

            if (midi_note_data.start_time <= elapsed_time){
                current_note++;
                pitch = midi_note_data.pitch;
                Log.d("MUSIC", "Note time " + midi_note_data.start_time + " ThreadTime "+ elapsed_time);
                sounds.play(tone, 1.0f, 1.0f, 0, 0, notes[pitch]);                  
            }

            if (current_note > MIDI.track_data.size()-1){
                ready = -2;
            }

       }else if (ready == 0){
            start_time = SystemClock.currentThreadTimeMillis();
            Log.d("MUSIC", "Start time "+start_time);
            ready = 1;
       }
    }
4

1 に答える 1

5

SystemClock.currentThreadTimeMillis() を使用しています。これは、現在のスレッドが実行されている時間です。Android では、UI スレッドが実際に実行されているのは半分の時間だけだと思います。(残りの半分は残りのオペレーティング システム用です!)

System.currentTimeMillis() に切り替えると、問題が解決されます。

さまざまな時間測定システムについて詳しくは、こちらをご覧ください。

于 2012-08-18T20:54:04.823 に答える