onPeriodicNotification() has the jitters on *some* devices
Why does onPeriodicNotification() behave so erratically?
Background
I'm working on an audio visualizer for Android that samples from the microphone using AudioRecord.read() (16-bit mono). I've done quite a bit of testing with sample rates and frame periods for setPositionNotificationPeriod(). In the end, I settled on: Sample Rate: 8000 Frame Period: Sample Rate * 41 / 1000 = 328 Buffer Size: 5 * Sample RateThe frame period is 41 ms which I chose because I want ~24 frames per second for my visualizer.
I thought that drawing to canvas at this rate would be a problem at first, but after testing on the DroidX and Nexus One, I was getting amazing performance. I can drop the latency to 20 ms on these devices without buffer-overruns but have no need to.
Once I started testing on the Galaxy S and Nexus S, my performance tanked. This seemed odd since the Nexus S outperforms both devices by a large degree. After eliminating drawing and calculations as being the problem, I put timing calls in o开发者_开发技巧nPeriodicNotification(). I was able to confirm that the issue is due to this callback being called at willy-nilly time intervals and I do not understand why.
Creating a Fair Benchmark
As a fair test, I took all of my audio processing and drawing out of the loop such that all my app does is read audio in a loop and log data in onPeriodicNotification(). I set the frame period to 100 ms and used the following timing code:currentTime = SystemClock.elapsedRealtime();
Log.v(TAG, "time since last record update: " + (currentTime - lastTime));
lastTime = currentTime;
Finally, I sampled data for 5-minutes on each device. On the DroidX, I get about what I expect:
# Points: 3008 Min: 92 Max: 105 Avg: 100 StdDev: 6.64This seems reasonable and I'm willing to live with this. On the Galaxy S, I get this:
# Points: 3004 Min: 0! Max: 274 Avg: 100.05 StdDev: 126.30?!?With a StdDev of 126, this means that a subsequent set of timing calls often looks like this [253, 0, 1, 258, 1, 0, 263].
Conclusion & other misc data
While performing these tests, I kept an eye on CPU usage. My process hovers around 2-3% CPU usage with plenty of overhead to work with. I notice that if I increase the latency between notifications to around 250 ms, the Galaxy S begins behaving as I would expect (the stddev drops to around 6-7). Unfortunately, 250 ms is far from being a usable latency for audio visualization.After typing all this I can't help but feel this better belongs in some bug report, but then again this is Samsung we're talking about and we know they have no internet android bug reporting presence :(
Alternatives, insights and experience are greatly appreciated.
Ultimately this seems to come down to the audio driver. I've found that Samsung's audio implementation results in incredibly high latency whereas Motorola, HTC and others are sufficiently low enough that I don't notice.
Low latency audio has been on the bug list for a long time, so perhaps this isn't surprising. If you are doing realtime audio visualization, prepare to be disappointed on Samsung devices :(
精彩评论