3

高周波音波を介して非常に低帯域幅の通信を可能にするアプリの作成に取り組んでいます。周波数を作成し、フーリエ変換を実行できるようになりました (Audalyzer 用のMoonblinkのオープン ソース コードの助けを借りて)。

しかし、ここに私の問題があります。正しいタイミングでコードを実行することができません。コードを 10 ミリ秒ごとに実行したいとします。これを行うにはどうすればよいでしょうか。

TimerTask を使用してみましたが、コードが実際に実行されるまでに最大 100 ミリ秒の大きな遅延があります。

また、現在の時刻にpingを実行し、その時間が経過したときにのみ実行するだけで、この方法を試しました。しかし、まだ遅延の問題があります。何かアイデアはありますか?

Thread analysis = new Thread(new Runnable()
{
    @Override
    public void run()
    {
        android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY);

        long executeTime = System.currentTimeMillis();

        manualAnalyzer.measureStart();
        while (FFTransforming) 
        {          
            if(System.currentTimeMillis() >= executeTime)
            {
                //Reset the timer to execute again in 10ms
                executeTime+=10;

                //Perform Fourier Transform
                manualAnalyzer.doUpdate(0);

                //TODO: Analyze the results of the transform here...

            }
        }
        manualAnalyzer.measureStop();
    }
});
analysis.start();
4

3 に答える 3

2

まったく異なるアプローチをお勧めします。コードをリアルタイムで実行しようとしないでください。

代わりに、関心のあるイベントを含む期間にわたって継続的に録音(または再生)することにより、リアルタイムで実行される低レベルのオーディオコードのみに依存します。

次に、コードはこれとは多少非同期に実行され、オーディオバッファによって分離されます。コードの時間感覚は、実行時のシステムクロックではなく、操作するオーディオデータの定義されたサンプル間隔によって決まります。(つまり、48 Kspを使用している場合、10 mS後は480サンプル後です)

送信が発生すると予想される時間枠を広げるために、デバイス間の相互作用を管理するプロトコルを変更する必要がある場合があります。つまり、「パケット」内の実際の変調とシンボルに関して正確なタイミングをとることができますが、パケットがいつ送受信されるかを決定する際にほぼ同じ精度を期待するべきではありません。パケットを「見つける」必要があります。ノイズを含む長い録音の中で。

于 2012-04-27T19:31:56.010 に答える
1

あなたのスレッド/ループ戦略は、おそらくあなたが得ようとしているのとほぼ同じです。ただし、10 ミリ秒は多くの時間ではなく、ほとんどの Android デバイスはそれほど強力ではありません。また、フーリエ変換を行うには多くの作業が必要です。10 ミリ秒でそれほど多くの作業を実行できる可能性は低いと思います。その期間を延ばす必要があると思います。

于 2012-04-25T20:37:11.977 に答える
1

doUpdate の実行時間を考慮に入れるようにコードを変更しました。System.nanoTime() を使用すると、精度も向上します。

    public void run() {
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY);

long executeTime=0;        
long nextTime = System.nanoTime();

manualAnalyzer.measureStart();
while (FFTransforming) 
{          
    if(System.nanoTime() >= nextTime)
    {
        executeTime = System.nanoTime();
        //Perform Fourier Transform
        manualAnalyzer.doUpdate(0);
        //TODO: Analyze the results of the transform here...
        executeTime = System.nanoTime() - executeTime;
        //guard against the case that doUpdate took longer than 10ms
        final long i = executeTime/10000000;
        //set the timer to execute again at the next full 10ms intervall
        nextTime+= 10000000+ i*10000000 
    }
}
manualAnalyzer.measureStop();
    }

他に何ができますか?

  • ガベージコレクションをなくす
  • NDK でネイティブに移行します (単なるアイデアです。これは何のメリットもありません)。
于 2012-04-27T19:25:21.103 に答える