Domanda

I am implementing a RTP receiver. It receives UDP packets, decodes the codec and writes the PCM samples to an AudioTrack for playback. A problem seems to be, that AudioTrack.write is blocking and as such I’ll miss UDP packets in the meantime.

Is there any known solution on how to deal with this problem?

I tried using my own buffer for audio data and setNotificationMarkerPosition, but it seems, the audioTrack will only play once it’s buffer is filled to some degree and as such the marker position is never reached or audioTrack.write becomes blocking again.

I also tried doing audioTrack.pause() before each write and then .play() again, but that seems to impact sound quality noticably.

È stato utile?

Soluzione

I don't know whether you have solved your problem or not, I have some problem. The best I could do is to grab UDP packets in a thread into ArrayBlockingQueue(ABQ), and play them in another thread taking one by one from ABQ. But this time playing suffers(not all devices, some devices are cool with double thread) and size of ABQ grows which means delay increases. So I check the size and drop some packets systematically(simply not writing into AudioTrack) in order to decrease delay, but it is your call if you are okay with delay.

One more thing, I am increasing priority of threads as such:

private class Player extends Thread {
  public void run() {
     Process.setThreadPriority(Process.THREAD_PRIORITY_AUDIO );
       ....
  }
}

which gives better speed.

The solution is still blocking in a manner but, UDP packets wont be blocked by player until ABQ size increases as its capacity.

Altri suggerimenti

I think I might have a more attractive solution than the "add a buffer and a thread" solution. That solution adds some latency to your (presumably) latency sensitive system. Here's what you can do:

Note the buffer size of your AudioTrack. Then keep track of how many bytes have been written to the buffer in the last X milliseconds (this should be doable in a not-too-computationally-intense manner), where X is the number of milliseconds of audio that you can fit into the buffer (simple calculation based on buffer size and sampling rate and quantization rate (bits/sample) and number of channels). If you've written "buffer size" amount of data in X milliseconds, then you should drop the packet of audio. Note that dropping packets is going to be a symptom of the "add a buffer and a thread" solution, also.

You may want to add a small threshold so that you never actually fill the buffer (assume the buffer is a little smaller than it actually is).

Good luck!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top