Resolves issue with audio playback where audio playback stops working.

Potential existed for the audio output class to become unsynchronized
with the underlying source data line and attempt to perform a blocking
write to the data line when the data line doesn't have the capacity to
accept the full buffer, and the data line is not started.  Thus,
playback could potentially stay in a persitent blocked state.

Refactored Mono and Stereo audio output implementations to push the
audio buffer queue processing into the parent abstract class.

AudioManager was updated to remove the last time active timestamp out 
of the audio manager and down into the audio output to remove duplicate
timestamp accounting.
This commit is contained in:
denny
2016-02-20 08:53:09 -05:00
parent 894ebeb040
commit a7da60cd27
5 changed files with 416 additions and 583 deletions

View File

@@ -1,5 +1,3 @@
package audio;
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014-2016 Dennis Sheirer
@@ -17,6 +15,8 @@ package audio;
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package audio;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -429,19 +429,17 @@ public class AudioManager implements Listener<AudioPacket>, IAudioController
* output and maintains current state information about the audio activity
* received form the source.
*/
public class AudioOutputConnection implements Listener<AudioEvent>
public class AudioOutputConnection
{
private static final int DISCONNECTED = -1;
private AudioOutput mAudioOutput;
private int mPriority = 0;
private long mLastActivity = System.currentTimeMillis();
private int mSource = DISCONNECTED;
public AudioOutputConnection( AudioOutput audioOutput )
{
mAudioOutput = audioOutput;
mAudioOutput.addAudioEventListener( this );
}
public void receive( AudioPacket packet )
@@ -457,8 +455,6 @@ public class AudioManager implements Listener<AudioPacket>, IAudioController
updateLowestPriorityAssignment();
}
updateTimestamp();
if( mAudioOutput != null )
{
mAudioOutput.receive( packet );
@@ -481,11 +477,6 @@ public class AudioManager implements Listener<AudioPacket>, IAudioController
}
}
private void updateTimestamp()
{
mLastActivity = System.currentTimeMillis();
}
/**
* Terminates the audio output and prepares this connection for disposal
*/
@@ -518,7 +509,8 @@ public class AudioManager implements Listener<AudioPacket>, IAudioController
public void connect( int source )
{
mSource = source;
updateTimestamp();
mAudioOutput.updateTimestamp();
}
/**
@@ -536,6 +528,7 @@ public class AudioManager implements Listener<AudioPacket>, IAudioController
public void disconnect()
{
mSource = DISCONNECTED;
mPriority = 0;
}
/**
@@ -544,28 +537,12 @@ public class AudioManager implements Listener<AudioPacket>, IAudioController
*/
public boolean isInactive()
{
return mLastActivity != Long.MAX_VALUE &&
mLastActivity + AUDIO_TIMEOUT < System.currentTimeMillis();
return ( mAudioOutput.getLastActivityTimestamp() + AUDIO_TIMEOUT ) < System.currentTimeMillis();
}
public int getPriority()
{
return mPriority;
}
@Override
public void receive( AudioEvent event )
{
switch( event.getType() )
{
case AUDIO_STARTED:
case AUDIO_STOPPED:
case AUDIO_CONTINUATION:
updateTimestamp();
break;
default:
break;
}
}
}
}