我正在努力创建一个允许通过高频声波进行极低带宽通信的应用。我已经达到了可以创建频率并进行傅里叶变换的程度(借助Moonblink的Audalyzer开源代码)。
但是这是我的问题:我无法让代码以正确的时序运行。假设我想要每10ms执行一段代码,我将如何进行此操作?
我尝试过使用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();
答案 0 :(得分:2)
我建议采用一种截然不同的方法:不要试图实时运行 代码。
相反,只依靠实时运行的低级音频代码,通过连续录制(或播放)一段时间来包含感兴趣的事件。
然后,您的代码与此异步运行,并通过音频缓冲区解耦。您的代码的时间感不是由执行时的系统时钟决定的,而是由您使用的音频数据的定义的采样间间隔决定的。 (即,如果你使用48 Ksps,那么10 mS之后是480个样本)
您可能需要修改管理设备之间交互的协议,以拓宽可能发生传输的时间窗口。即,您可以对“数据包”中的实际调制和符号进行精确计时,但在确定何时发送或接收数据包时,您不应期望几乎相同的精度 - 您必须“找到”它在一个包含噪音的较长记录中。
答案 1 :(得分:1)
您的线程/循环策略可能与您将获得的大致相同。但是,10ms并不是很多时间,大多数Android设备都不是超级强大,而傅立叶变换则需要做很多工作。我发现你不可能在10ms内完成那么多工作。我怀疑你将不得不增加那段时间。
答案 2 :(得分: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();
}
你还能做什么?