Audio outputs - added exception handler to catch any errors that occur

while the buffer processor thread is running.

Added check for 0 space available in data line buffers to avoid trying
to write a zero-length audio chunk to the data line.

Added thread sleep for 100 milliseconds when we detect that the data
line buffer is full, to allow time for the data line to drain before we
check it again.  Hopefully this should minimize the chattering during
playback when the code was repeatedly hitting the available() method to
check for space availability.
This commit is contained in:
denny
2016-01-22 16:35:18 -05:00
parent 676d26f4d8
commit 1db6779dec
2 changed files with 152 additions and 122 deletions

View File

@@ -24,7 +24,6 @@ import audio.AudioEvent;
import audio.AudioFormats; import audio.AudioFormats;
import audio.AudioPacket; import audio.AudioPacket;
import audio.AudioPacket.Type; import audio.AudioPacket.Type;
import audio.output.StereoAudioOutput.QueueProcessor;
import controller.NamingThreadFactory; import controller.NamingThreadFactory;
/** /**
@@ -144,12 +143,10 @@ public class MonoAudioOutput extends AudioOutput
{ {
private AtomicBoolean mProcessing = new AtomicBoolean(); private AtomicBoolean mProcessing = new AtomicBoolean();
public QueueProcessor()
{
}
@Override @Override
public void run() public void run()
{
try
{ {
/* The mProcessing flag ensures that only one instance of the /* The mProcessing flag ensures that only one instance of the
* processor can run at any given time */ * processor can run at any given time */
@@ -206,16 +203,32 @@ public class MonoAudioOutput extends AudioOutput
if( available < toWrite ) if( available < toWrite )
{ {
wrote += mOutput.write( buffer.array(), wrote, if( available > 0 )
available ); {
wrote += mOutput.write( buffer.array(),
wrote, available );
checkStart();
}
else
{
try
{
Thread.sleep( 100 );
}
catch ( InterruptedException e )
{
mLog.debug( "Mono Audio Output - interrupted while sleeping awaiting buffer drain" );
}
}
} }
else else
{ {
wrote += mOutput.write( buffer.array(), wrote, wrote += mOutput.write( buffer.array(), wrote,
toWrite ); toWrite );
}
checkStart(); checkStart();
}
toWrite = buffer.array().length - wrote; toWrite = buffer.array().length - wrote;
} }
@@ -236,6 +249,11 @@ public class MonoAudioOutput extends AudioOutput
mProcessing.set( false ); mProcessing.set( false );
} }
} }
catch( Exception e )
{
mLog.error( "Error while processing audio buffers", e );
}
}
private void checkStart() private void checkStart()
{ {

View File

@@ -176,6 +176,8 @@ public class StereoAudioOutput extends AudioOutput
@Override @Override
public void run() public void run()
{
try
{ {
/* The mProcessing flag ensures that only one instance of the /* The mProcessing flag ensures that only one instance of the
* processor can run at any given time */ * processor can run at any given time */
@@ -221,16 +223,21 @@ public class StereoAudioOutput extends AudioOutput
if( available < toWrite ) if( available < toWrite )
{ {
wrote += mOutput.write( buffer.array(), wrote, if( available > 0 )
available ); {
wrote += mOutput.write( buffer.array(),
wrote, available );
checkStart();
}
} }
else else
{ {
wrote += mOutput.write( buffer.array(), wrote, wrote += mOutput.write( buffer.array(), wrote,
toWrite ); toWrite );
}
checkStart(); checkStart();
}
toWrite = buffer.array().length - wrote; toWrite = buffer.array().length - wrote;
} }
@@ -251,6 +258,11 @@ public class StereoAudioOutput extends AudioOutput
mProcessing.set( false ); mProcessing.set( false );
} }
} }
catch( Exception e )
{
mLog.error( "Error while processing audio buffers", e );
}
}
private void checkStart() private void checkStart()
{ {