diff --git a/src/org/jitsi/impl/neomedia/jmfext/media/protocol/portaudio/PortAudioStream.java b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/portaudio/PortAudioStream.java index 4b75cbbc7ff24e038078516f4352e80ab6c89dcf..0871f2e5fa1e75418fb63406ac7055de6809e358 100644 --- a/src/org/jitsi/impl/neomedia/jmfext/media/protocol/portaudio/PortAudioStream.java +++ b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/portaudio/PortAudioStream.java @@ -376,21 +376,12 @@ else if (!started) */ if (message != null) { - boolean interrupted = false; - - try - { - Thread.sleep(Pa.DEFAULT_MILLIS_PER_BUFFER); - } - catch (InterruptedException ie) - { - interrupted = true; - } - if (interrupted) - Thread.currentThread().interrupt(); + yield(); throw new IOException(message); } + long paErrorCode = Pa.paNoError; + try { /* @@ -416,14 +407,16 @@ else if (!started) { Pa.ReadStream(stream, bufferData, framesPerBuffer); } - catch (PortAudioException paex) + catch (PortAudioException pae) { - logger.error("Failed to read from PortAudio stream.", paex); + paErrorCode = pae.getErrorCode(); - IOException ioex = new IOException(paex.getLocalizedMessage()); + logger.error("Failed to read from PortAudio stream.", pae); - ioex.initCause(paex); - throw ioex; + IOException ioe = new IOException(pae.getLocalizedMessage()); + + ioe.initCause(pae); + throw ioe; } // if we have some volume setting apply them @@ -452,6 +445,14 @@ else if (!started) streamIsBusy = false; notifyAll(); } + + /* + * If a timeout has occurred in the method Pa.ReadStream, give the + * application a little time to allow it to possibly get its act + * together. + */ + if (Pa.paTimedOut == paErrorCode) + yield(); } } @@ -618,4 +619,24 @@ private void waitWhileStreamIsBusy() if (interrupted) Thread.currentThread().interrupt(); } + + /** + * Causes the currently executing thread to temporarily pause and allow + * other threads to execute. + */ + public static void yield() + { + boolean interrupted = false; + + try + { + Thread.sleep(Pa.DEFAULT_MILLIS_PER_BUFFER); + } + catch (InterruptedException ie) + { + interrupted = true; + } + if (interrupted) + Thread.currentThread().interrupt(); + } } diff --git a/src/org/jitsi/impl/neomedia/jmfext/media/renderer/audio/PortAudioRenderer.java b/src/org/jitsi/impl/neomedia/jmfext/media/renderer/audio/PortAudioRenderer.java index 1c176ceeef5ab5a2820276f45cb6e8bcefca6f9d..1a6ebc2a42a1909198aab9523d6b8470194eadae 100644 --- a/src/org/jitsi/impl/neomedia/jmfext/media/renderer/audio/PortAudioRenderer.java +++ b/src/org/jitsi/impl/neomedia/jmfext/media/renderer/audio/PortAudioRenderer.java @@ -670,6 +670,9 @@ public int process(Buffer buffer) else streamIsBusy = true; } + + long paErrorCode = Pa.paNoError; + try { process( @@ -677,9 +680,11 @@ public int process(Buffer buffer) buffer.getOffset(), buffer.getLength()); } - catch (PortAudioException paex) + catch (PortAudioException pae) { - logger.error("Failed to process Buffer.", paex); + paErrorCode = pae.getErrorCode(); + + logger.error("Failed to process Buffer.", pae); } finally { @@ -688,6 +693,14 @@ public int process(Buffer buffer) streamIsBusy = false; notifyAll(); } + + /* + * If a timeout has occurred in the method Pa.WriteStream, give the + * application a little time to allow it to possibly get its act + * together. + */ + if (Pa.paTimedOut == paErrorCode) + PortAudioStream.yield(); } return BUFFER_PROCESSED_OK; } diff --git a/src/org/jitsi/impl/neomedia/portaudio/Pa.java b/src/org/jitsi/impl/neomedia/portaudio/Pa.java index 46223bd815e436d707284f85076c33aa7ff239d0..49babcdc0ecb0c6bfd4edf817bb332f1e81c3301 100644 --- a/src/org/jitsi/impl/neomedia/portaudio/Pa.java +++ b/src/org/jitsi/impl/neomedia/portaudio/Pa.java @@ -75,11 +75,17 @@ public final class Pa public static final int paNoDevice = -1; /** - * The error code defined by the native PortAudio library to signal that no - * error is detected/reported. + * The <tt>PaErrorCode</tt> value defined by the native PortAudio library to + * signal that no error is detected/reported. */ public static final int paNoError = 0; + /** + * The <tt>PaErrorCode</tt> value defined by the native PortAudio library to + * signal that a timeout has occurred. + */ + public static final int paTimedOut = -9987; + /** * The name of the <tt>double</tt> property which determines the suggested * latency to be used when opening PortAudio streams.