0

Transmitterから定期的な信号 (1 分あたりのビート数) を受信して​​おり、1/1、1/2、1/4、1/8、1/16 などのように、周期の一部でメソッドを呼び出したいと考えています。 。 ノート。

これに対する私の解決策は、スレッドを作成し、ビジー状態で待機してからメソッドを実行することです。ここでの問題は、信号をリッスンし、処理して送り返すと、数ミリ秒の遅延が発生することです (システムによって異なります)。

したがって、着信信号とスレッドの定期的な信号の間の遅延を特定したいと思います。遅延が != 0 の場合は、現在のスレッドを停止し、「bpm - 遅延」ミリ秒後に新しいスレッドを開始します。これはどのように行うことができますか?

図:

送信機信号: |----|----|----|----|

******ランナー信号: |----|----|----|----|

ランナー信号を「onePeriod - delay」ミリ秒遅らせる:

送信機信号: |----|----|----|----|

***"ランナー信号:**** |----|----|----|----|

両方の信号が同期しています。

public class Quantiser implements Receiver{
    private int[] bpmsInMillis = new int[4];
    private int bpmInMillis=0;
    private double smallestNote = 1;
    private long period=0;

    private long fire=0;
    private long prevTimeStamp=0;

    private Runnable runny = new Runnable() {
        @Override
        public void run() {
            while(true){
                fire = System.nanoTime() + period;
                while(System.nanoTime() < fire){} // busy wait
                // Call some methods here.
            }
        }
    };
    private Thread thread = new Thread(runny);


    @Override
    public void send(MidiMessage message, long timeStamp) {

        // Calculate average bpm
        for(int i=0; i<bpmsInMillis.length-1;i++)
            bpmsInMillis[i] = bpmsInMillis[i+1];

        bpmsInMillis[bpmsInMillis.length-1] = (int) ((timeStamp - prevTimeStamp) / 1000);

        bpmInMillis = arithmeticMean(bpmsInMillis);
        prevTimeStamp = timeStamp;

        period = (long) (bpmInMillis * smallestNote * 1000000);

        if(!thread.isAlive()) {
            thread.start();
        }
        /*
        else{
            Calculate delay between signal and thread-signal.
            if(delay != 0){                    
                Delay new thread by "bpm - delay" milliseconds.
                Stop old thread.
                Start new thread.
            }
        */            
    }

    @Override
    public void close() {

    }
4

2 に答える 2

0

一般に、サウンド (通常は MIDI ではなくサンプリング) を扱う場合、経過時間よりもフレーム カウントを使用する方が正確であることがわかります。経過時間とともに、不明な点が多すぎます (スレッド スライス、ガベージ コレクションなど)。遅延は異なる場合がありますが、44100 フレーム (フォーマットの場合) は常に 1 秒です。

MIDI では、すべてのイベントにそのイベントが発生する時間のフィールドがあるわけではありませんか? ビート/小節と経過時間の両方の読み取り値を見てきました。私は、既存の Midi ストリーム上で何らかのポジショニングを行う際に、リアルタイムのタイム スタンプではなくその情報を使用します。

これが着信が ASAP/リアルタイムであるが、量子化されたものを通過させたい場合、着信がそれを持っていなくても、発信 Midi にスケジューリング情報を入れることができますか? そうすれば、位置決めのためのしっかりした基準点が得られます。

リアルタイムでの参照。Java での低遅延オーディオ処理: https://diuf.unifr.ch/main/pai/sites/diuf.unifr.ch.main.pai/files/publications/2007_Juillerat_Mueller_Schubiger-Banz_Real_Time.pdf

于 2015-02-13T19:36:58.537 に答える