@ -58,7 +58,6 @@ using namespace aaudio;
AudioStreamInternal : : AudioStreamInternal ( AAudioServiceInterface & serviceInterface , bool inService )
: AudioStream ( )
, mClockModel ( )
, mAudioEndpoint ( )
, mServiceStreamHandle ( AAUDIO_HANDLE_INVALID )
, mInService ( inService )
, mServiceInterface ( serviceInterface )
@ -74,7 +73,6 @@ AudioStreamInternal::~AudioStreamInternal() {
aaudio_result_t AudioStreamInternal : : open ( const AudioStreamBuilder & builder ) {
aaudio_result_t result = AAUDIO_OK ;
int32_t capacity ;
int32_t framesPerBurst ;
int32_t framesPerHardwareBurst ;
AAudioStreamRequest request ;
@ -173,7 +171,8 @@ aaudio_result_t AudioStreamInternal::open(const AudioStreamBuilder &builder) {
}
// Configure endpoint based on descriptor.
result = mAudioEndpoint . configure ( & mEndpointDescriptor , getDirection ( ) ) ;
mAudioEndpoint = std : : make_unique < AudioEndpoint > ( ) ;
result = mAudioEndpoint - > configure ( & mEndpointDescriptor , getDirection ( ) ) ;
if ( result ! = AAUDIO_OK ) {
goto error ;
}
@ -201,9 +200,10 @@ aaudio_result_t AudioStreamInternal::open(const AudioStreamBuilder &builder) {
}
mFramesPerBurst = framesPerBurst ; // only save good value
capacity = mEndpointDescriptor . dataQueueDescriptor . capacityInFrames ;
if ( capacity < mFramesPerBurst | | capacity > MAX_BUFFER_CAPACITY_IN_FRAMES ) {
ALOGE ( " %s - bufferCapacity out of range = %d " , __func__ , capacity ) ;
mBufferCapacityInFrames = mEndpointDescriptor . dataQueueDescriptor . capacityInFrames ;
if ( mBufferCapacityInFrames < mFramesPerBurst
| | mBufferCapacityInFrames > MAX_BUFFER_CAPACITY_IN_FRAMES ) {
ALOGE ( " %s - bufferCapacity out of range = %d " , __func__ , mBufferCapacityInFrames ) ;
result = AAUDIO_ERROR_OUT_OF_RANGE ;
goto error ;
}
@ -239,7 +239,7 @@ aaudio_result_t AudioStreamInternal::open(const AudioStreamBuilder &builder) {
// You can use this offset to reduce glitching.
// You can also use this offset to force glitching. By iterating over multiple
// values you can reveal the distribution of the hardware timing jitter.
if ( mAudioEndpoint . isFreeRunning ( ) ) { // MMAP?
if ( mAudioEndpoint - > isFreeRunning ( ) ) { // MMAP?
int32_t offsetMicros = ( getDirection ( ) = = AAUDIO_DIRECTION_OUTPUT )
? AAudioProperty_getOutputMMapOffsetMicros ( )
: AAudioProperty_getInputMMapOffsetMicros ( ) ;
@ -251,7 +251,7 @@ aaudio_result_t AudioStreamInternal::open(const AudioStreamBuilder &builder) {
mTimeOffsetNanos = offsetMicros * AAUDIO_NANOS_PER_MICROSECOND ;
}
setBufferSize ( capacity / 2 ) ; // Default buffer size to match Q
setBufferSize ( mBufferCapacityInFrames / 2 ) ; // Default buffer size to match Q
setState ( AAUDIO_STREAM_STATE_OPEN ) ;
@ -280,6 +280,11 @@ aaudio_result_t AudioStreamInternal::release_l() {
mServiceInterface . closeStream ( serviceStreamHandle ) ;
mCallbackBuffer . reset ( ) ;
// Update local frame counters so we can query them after releasing the endpoint.
getFramesRead ( ) ;
getFramesWritten ( ) ;
mAudioEndpoint . reset ( ) ;
result = mEndPointParcelable . close ( ) ;
aaudio_result_t result2 = AudioStream : : release_l ( ) ;
return ( result ! = AAUDIO_OK ) ? result : result2 ;
@ -538,7 +543,7 @@ aaudio_result_t AudioStreamInternal::onEventFromServer(AAudioServiceMessage *mes
case AAUDIO_SERVICE_EVENT_DISCONNECTED :
// Prevent hardware from looping on old data and making buzzing sounds.
if ( getDirection ( ) = = AAUDIO_DIRECTION_OUTPUT ) {
mAudioEndpoint . eraseDataMemory ( ) ;
mAudioEndpoint - > eraseDataMemory ( ) ;
}
result = AAUDIO_ERROR_DISCONNECTED ;
setState ( AAUDIO_STREAM_STATE_DISCONNECTED ) ;
@ -564,7 +569,10 @@ aaudio_result_t AudioStreamInternal::drainTimestampsFromService() {
while ( result = = AAUDIO_OK ) {
AAudioServiceMessage message ;
if ( mAudioEndpoint . readUpCommand ( & message ) ! = 1 ) {
if ( ! mAudioEndpoint ) {
break ;
}
if ( mAudioEndpoint - > readUpCommand ( & message ) ! = 1 ) {
break ; // no command this time, no problem
}
switch ( message . what ) {
@ -592,7 +600,10 @@ aaudio_result_t AudioStreamInternal::processCommands() {
while ( result = = AAUDIO_OK ) {
AAudioServiceMessage message ;
if ( mAudioEndpoint . readUpCommand ( & message ) ! = 1 ) {
if ( ! mAudioEndpoint ) {
break ;
}
if ( mAudioEndpoint - > readUpCommand ( & message ) ! = 1 ) {
break ; // no command this time, no problem
}
switch ( message . what ) {
@ -625,7 +636,7 @@ aaudio_result_t AudioStreamInternal::processData(void *buffer, int32_t numFrames
const char * fifoName = " aaRdy " ;
ATRACE_BEGIN ( traceName ) ;
if ( ATRACE_ENABLED ( ) ) {
int32_t fullFrames = mAudioEndpoint . getFullFramesAvailable ( ) ;
int32_t fullFrames = mAudioEndpoint - > getFullFramesAvailable ( ) ;
ATRACE_INT ( fifoName , fullFrames ) ;
}
@ -654,7 +665,7 @@ aaudio_result_t AudioStreamInternal::processData(void *buffer, int32_t numFrames
if ( timeoutNanoseconds = = 0 ) {
break ; // don't block
} else if ( wakeTimeNanos ! = 0 ) {
if ( ! mAudioEndpoint . isFreeRunning ( ) ) {
if ( ! mAudioEndpoint - > isFreeRunning ( ) ) {
// If there is software on the other end of the FIFO then it may get delayed.
// So wake up just a little after we expect it to be ready.
wakeTimeNanos + = mWakeupDelayNanos ;
@ -679,12 +690,12 @@ aaudio_result_t AudioStreamInternal::processData(void *buffer, int32_t numFrames
ALOGW ( " processData(): past deadline by %d micros " ,
( int ) ( ( wakeTimeNanos - deadlineNanos ) / AAUDIO_NANOS_PER_MICROSECOND ) ) ;
mClockModel . dump ( ) ;
mAudioEndpoint . dump ( ) ;
mAudioEndpoint - > dump ( ) ;
break ;
}
if ( ATRACE_ENABLED ( ) ) {
int32_t fullFrames = mAudioEndpoint . getFullFramesAvailable ( ) ;
int32_t fullFrames = mAudioEndpoint - > getFullFramesAvailable ( ) ;
ATRACE_INT ( fifoName , fullFrames ) ;
int64_t sleepForNanos = wakeTimeNanos - currentTimeNanos ;
ATRACE_INT ( " aaSlpNs " , ( int32_t ) sleepForNanos ) ;
@ -696,7 +707,7 @@ aaudio_result_t AudioStreamInternal::processData(void *buffer, int32_t numFrames
}
if ( ATRACE_ENABLED ( ) ) {
int32_t fullFrames = mAudioEndpoint . getFullFramesAvailable ( ) ;
int32_t fullFrames = mAudioEndpoint - > getFullFramesAvailable ( ) ;
ATRACE_INT ( fifoName , fullFrames ) ;
}
@ -730,11 +741,15 @@ aaudio_result_t AudioStreamInternal::setBufferSize(int32_t requestedFrames) {
adjustedFrames = std : : min ( maximumSize , adjustedFrames ) ;
}
// Clip against the actual size from the endpoint.
int32_t actualFrames = 0 ;
mAudioEndpoint . setBufferSizeInFrames ( maximumSize , & actualFrames ) ;
// actualFrames should be <= actual maximum size of endpoint
adjustedFrames = std : : min ( actualFrames , adjustedFrames ) ;
if ( mAudioEndpoint ) {
// Clip against the actual size from the endpoint.
int32_t actualFrames = 0 ;
// Set to maximum size so we can write extra data when ready in order to reduce glitches.
// The amount we keep in the buffer is controlled by mBufferSizeInFrames.
mAudioEndpoint - > setBufferSizeInFrames ( maximumSize , & actualFrames ) ;
// actualFrames should be <= actual maximum size of endpoint
adjustedFrames = std : : min ( actualFrames , adjustedFrames ) ;
}
mBufferSizeInFrames = adjustedFrames ;
ALOGV ( " %s(%d) returns %d " , __func__ , requestedFrames , adjustedFrames ) ;
@ -746,7 +761,7 @@ int32_t AudioStreamInternal::getBufferSize() const {
}
int32_t AudioStreamInternal : : getBufferCapacity ( ) const {
return m AudioEndpoint. get BufferCapacityInFrames( ) ;
return m BufferCapacityInFrames;
}
int32_t AudioStreamInternal : : getFramesPerBurst ( ) const {
@ -759,5 +774,5 @@ aaudio_result_t AudioStreamInternal::joinThread(void** returnArg) {
}
bool AudioStreamInternal : : isClockModelInControl ( ) const {
return isActive ( ) & & mAudioEndpoint . isFreeRunning ( ) & & mClockModel . isRunning ( ) ;
return isActive ( ) & & mAudioEndpoint - > isFreeRunning ( ) & & mClockModel . isRunning ( ) ;
}