@ -130,29 +130,106 @@ aaudio_result_t AudioStream::safeStart() {
}
aaudio_result_t AudioStream : : safePause ( ) {
if ( ! isPauseSupported ( ) ) {
return AAUDIO_ERROR_UNIMPLEMENTED ;
}
std : : lock_guard < std : : mutex > lock ( mStreamLock ) ;
if ( collidesWithCallback ( ) ) {
ALOGE ( " %s cannot be called from a callback! " , __func__ ) ;
return AAUDIO_ERROR_INVALID_STATE ;
}
switch ( getState ( ) ) {
// Proceed with pausing.
case AAUDIO_STREAM_STATE_STARTING :
case AAUDIO_STREAM_STATE_STARTED :
case AAUDIO_STREAM_STATE_DISCONNECTED :
break ;
// Transition from one inactive state to another.
case AAUDIO_STREAM_STATE_OPEN :
case AAUDIO_STREAM_STATE_STOPPED :
case AAUDIO_STREAM_STATE_FLUSHED :
setState ( AAUDIO_STREAM_STATE_PAUSED ) ;
return AAUDIO_OK ;
// Redundant?
case AAUDIO_STREAM_STATE_PAUSING :
case AAUDIO_STREAM_STATE_PAUSED :
return AAUDIO_OK ;
// Don't interfere with transitional states or when closed.
case AAUDIO_STREAM_STATE_STOPPING :
case AAUDIO_STREAM_STATE_FLUSHING :
case AAUDIO_STREAM_STATE_CLOSING :
case AAUDIO_STREAM_STATE_CLOSED :
default :
ALOGW ( " safePause() stream not running, state = %s " ,
AAudio_convertStreamStateToText ( getState ( ) ) ) ;
return AAUDIO_ERROR_INVALID_STATE ;
}
return requestPause ( ) ;
}
aaudio_result_t AudioStream : : safeFlush ( ) {
if ( ! isFlushSupported ( ) ) {
ALOGE ( " flush not supported for this stream " ) ;
return AAUDIO_ERROR_UNIMPLEMENTED ;
}
std : : lock_guard < std : : mutex > lock ( mStreamLock ) ;
if ( collidesWithCallback ( ) ) {
ALOGE ( " %s cannot be called from a callback! " , __func__ ) ;
ALOGE ( " stream cannot be flushed from a callback!" ) ;
return AAUDIO_ERROR_INVALID_STATE ;
}
aaudio_result_t result = AAudio_isFlushAllowed ( getState ( ) ) ;
if ( result ! = AAUDIO_OK ) {
return result ;
}
return requestFlush ( ) ;
}
aaudio_result_t AudioStream : : safeStop ( ) {
std : : lock_guard < std : : mutex > lock ( mStreamLock ) ;
if ( collidesWithCallback ( ) ) {
ALOGE ( " %s cannot be called from a callback! " , __func__ ) ;
ALOGE ( " stream cannot be stopped from a callback!" ) ;
return AAUDIO_ERROR_INVALID_STATE ;
}
switch ( getState ( ) ) {
// Proceed with stopping.
case AAUDIO_STREAM_STATE_STARTING :
case AAUDIO_STREAM_STATE_STARTED :
case AAUDIO_STREAM_STATE_DISCONNECTED :
break ;
// Transition from one inactive state to another.
case AAUDIO_STREAM_STATE_OPEN :
case AAUDIO_STREAM_STATE_PAUSED :
case AAUDIO_STREAM_STATE_FLUSHED :
setState ( AAUDIO_STREAM_STATE_STOPPED ) ;
return AAUDIO_OK ;
// Redundant?
case AAUDIO_STREAM_STATE_STOPPING :
case AAUDIO_STREAM_STATE_STOPPED :
return AAUDIO_OK ;
// Don't interfere with transitional states or when closed.
case AAUDIO_STREAM_STATE_PAUSING :
case AAUDIO_STREAM_STATE_FLUSHING :
case AAUDIO_STREAM_STATE_CLOSING :
case AAUDIO_STREAM_STATE_CLOSED :
default :
ALOGW ( " requestStop() stream not running, state = %s " ,
AAudio_convertStreamStateToText ( getState ( ) ) ) ;
return AAUDIO_ERROR_INVALID_STATE ;
}
return requestStop ( ) ;
}
@ -238,6 +315,7 @@ aaudio_result_t AudioStream::createThread(int64_t periodNanoseconds,
if ( err ! = 0 ) {
return AAudioConvert_androidToAAudioResult ( - errno ) ;
} else {
// TODO Use AAudioThread or maybe AndroidThread
// Name the thread with an increasing index, "AAudio_#", for debugging.
static std : : atomic < uint32_t > nextThreadIndex { 1 } ;
char name [ 16 ] ; // max length for a pthread_name