Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 06797a2d authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "aaudio: implement IPlayer for MMAP playback streams" into oc-dr1-dev

parents 00e2cbcf a2f296e0
Loading
Loading
Loading
Loading
+39 −4
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ AudioStreamInternal::AudioStreamInternal(AAudioServiceInterface &serviceInterfa
        , mAudioEndpoint()
        , mServiceStreamHandle(AAUDIO_HANDLE_INVALID)
        , mFramesPerBurst(16)
        , mStreamVolume(1.0f)
        , mServiceInterface(serviceInterface)
        , mInService(inService) {
}
@@ -175,6 +176,10 @@ aaudio_result_t AudioStreamInternal::open(const AudioStreamBuilder &builder) {
        }

        setState(AAUDIO_STREAM_STATE_OPEN);
        // only connect to AudioManager if this is a playback stream running in client process
        if (!mInService && getDirection() == AAUDIO_DIRECTION_OUTPUT) {
            init(android::PLAYER_TYPE_AAUDIO, AUDIO_USAGE_MEDIA);
        }
    }
    return result;
}
@@ -231,7 +236,7 @@ aaudio_result_t AudioStreamInternal::requestStart()
    startTime = AudioClock::getNanoseconds();
    mClockModel.start(startTime);
    setState(AAUDIO_STREAM_STATE_STARTING);
    aaudio_result_t result = mServiceInterface.startStream(mServiceStreamHandle);;
    aaudio_result_t result = AAudioConvert_androidToAAudioResult(startWithStatus());

    if (result == AAUDIO_OK && getDataCallbackProc() != nullptr) {
        // Launch the callback loop thread.
@@ -281,7 +286,7 @@ aaudio_result_t AudioStreamInternal::requestPauseInternal()

    mClockModel.stop(AudioClock::getNanoseconds());
    setState(AAUDIO_STREAM_STATE_PAUSING);
    return mServiceInterface.pauseStream(mServiceStreamHandle);
    return AAudioConvert_androidToAAudioResult(pauseWithStatus());
}

aaudio_result_t AudioStreamInternal::requestPause()
@@ -330,7 +335,7 @@ aaudio_result_t AudioStreamInternal::requestStopInternal()

    mClockModel.stop(AudioClock::getNanoseconds());
    setState(AAUDIO_STREAM_STATE_STOPPING);
    return mServiceInterface.stopStream(mServiceStreamHandle);
    return AAudioConvert_androidToAAudioResult(stopWithStatus());
}

aaudio_result_t AudioStreamInternal::requestStop()
@@ -446,7 +451,8 @@ aaudio_result_t AudioStreamInternal::onEventFromServer(AAudioServiceMessage *mes
            ALOGW("WARNING - processCommands() AAUDIO_SERVICE_EVENT_DISCONNECTED");
            break;
        case AAUDIO_SERVICE_EVENT_VOLUME:
            mVolumeRamp.setTarget((float) message->event.dataDouble);
            mStreamVolume = (float)message->event.dataDouble;
            doSetVolume();
            ALOGD("processCommands() AAUDIO_SERVICE_EVENT_VOLUME %lf",
                     message->event.dataDouble);
            break;
@@ -588,3 +594,32 @@ int32_t AudioStreamInternal::getFramesPerBurst() const {
aaudio_result_t AudioStreamInternal::joinThread(void** returnArg) {
    return AudioStream::joinThread(returnArg, calculateReasonableTimeout(getFramesPerBurst()));
}

void AudioStreamInternal::doSetVolume() {
    // No pan and only left volume is taken into account from IPLayer interface
    mVolumeRamp.setTarget(mStreamVolume * mVolumeMultiplierL /* * mPanMultiplierL */);
}


//------------------------------------------------------------------------------
// Implementation of PlayerBase
status_t AudioStreamInternal::playerStart() {
    return AAudioConvert_aaudioToAndroidStatus(mServiceInterface.startStream(mServiceStreamHandle));
}

status_t AudioStreamInternal::playerPause() {
    return AAudioConvert_aaudioToAndroidStatus(mServiceInterface.pauseStream(mServiceStreamHandle));
}

status_t AudioStreamInternal::playerStop() {
    return AAudioConvert_aaudioToAndroidStatus(mServiceInterface.stopStream(mServiceStreamHandle));
}

status_t AudioStreamInternal::playerSetVolume() {
    doSetVolume();
    return NO_ERROR;
}

void AudioStreamInternal::destroy() {
    baseDestroy();
}
+14 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#define ANDROID_AAUDIO_AUDIO_STREAM_INTERNAL_H

#include <stdint.h>
#include <media/PlayerBase.h>
#include <aaudio/AAudio.h>

#include "binding/IAAudioService.h"
@@ -34,7 +35,7 @@ using android::IAAudioService;
namespace aaudio {

// A stream that talks to the AAudioService or directly to a HAL.
class AudioStreamInternal : public AudioStream {
class AudioStreamInternal : public AudioStream, public android::PlayerBase  {

public:
    AudioStreamInternal(AAudioServiceInterface  &serviceInterface, bool inService);
@@ -89,6 +90,9 @@ public:
    // Calculate timeout based on framesPerBurst
    int64_t calculateReasonableTimeout();

    //PlayerBase virtuals
    virtual void destroy();

protected:

    aaudio_result_t processData(void *buffer,
@@ -124,6 +128,14 @@ protected:
    // Calculate timeout for an operation involving framesPerOperation.
    int64_t calculateReasonableTimeout(int32_t framesPerOperation);

    void doSetVolume();

    //PlayerBase virtuals
    virtual status_t playerStart();
    virtual status_t playerPause();
    virtual status_t playerStop();
    virtual status_t playerSetVolume();

    aaudio_format_t          mDeviceFormat = AAUDIO_FORMAT_UNSPECIFIED;

    IsochronousClockModel    mClockModel;      // timing model for chasing the HAL
@@ -135,6 +147,7 @@ protected:
    int32_t                  mXRunCount = 0;      // how many underrun events?

    LinearRamp               mVolumeRamp;
    float                    mStreamVolume;

    // Offset from underlying frame position.
    int64_t                  mFramesOffsetFromService = 0; // offset for timestamps
+10 −8
Original line number Diff line number Diff line
@@ -208,9 +208,12 @@ status_t AAudioConvert_aaudioToAndroidStatus(aaudio_result_t result) {
    status_t status;
    switch (result) {
    case AAUDIO_ERROR_DISCONNECTED:
    case AAUDIO_ERROR_INVALID_HANDLE:
    case AAUDIO_ERROR_NO_SERVICE:
        status = DEAD_OBJECT;
        break;
    case AAUDIO_ERROR_INVALID_HANDLE:
        status = BAD_TYPE;
        break;
    case AAUDIO_ERROR_INVALID_STATE:
        status = INVALID_OPERATION;
        break;
@@ -233,7 +236,6 @@ status_t AAudioConvert_aaudioToAndroidStatus(aaudio_result_t result) {
    case AAUDIO_ERROR_NO_FREE_HANDLES:
    case AAUDIO_ERROR_NO_MEMORY:
    case AAUDIO_ERROR_TIMEOUT:
    case AAUDIO_ERROR_NO_SERVICE:
    default:
        status = UNKNOWN_ERROR;
        break;
+36 −23
Original line number Diff line number Diff line
@@ -79,7 +79,7 @@ void PlayerBase::serviceReleasePlayer() {
    }
}

//FIXME temporary method while some AudioTrack state is outside of this class
//FIXME temporary method while some player state is outside of this class
void PlayerBase::reportEvent(player_state_t event) {
    servicePlayerEvent(event);
}
@@ -87,10 +87,30 @@ void PlayerBase::reportEvent(player_state_t event) {
status_t PlayerBase::startWithStatus() {
    status_t status = playerStart();
    if (status == NO_ERROR) {
        ALOGD("PlayerBase::start() from IPlayer");
        servicePlayerEvent(PLAYER_STATE_STARTED);
    } else {
        ALOGD("PlayerBase::start() no AudioTrack to start from IPlayer");
        ALOGW("PlayerBase::start() error %d", status);
    }
    return status;
}

status_t PlayerBase::pauseWithStatus() {
    status_t status = playerPause();
    if (status == NO_ERROR) {
        servicePlayerEvent(PLAYER_STATE_PAUSED);
    } else {
        ALOGW("PlayerBase::pause() error %d", status);
    }
    return status;
}


status_t PlayerBase::stopWithStatus() {
    status_t status = playerStop();
    if (status == NO_ERROR) {
        servicePlayerEvent(PLAYER_STATE_STOPPED);
    } else {
        ALOGW("PlayerBase::stop() error %d", status);
    }
    return status;
}
@@ -98,42 +118,36 @@ status_t PlayerBase::startWithStatus() {
//------------------------------------------------------------------------------
// Implementation of IPlayer
void PlayerBase::start() {
    ALOGD("PlayerBase::start() from IPlayer");
    (void)startWithStatus();
}

void PlayerBase::pause() {
    if (playerPause() == NO_ERROR) {
    ALOGD("PlayerBase::pause() from IPlayer");
        servicePlayerEvent(PLAYER_STATE_PAUSED);
    } else {
        ALOGD("PlayerBase::pause() no AudioTrack to pause from IPlayer");
    }
    (void)pauseWithStatus();
}


void PlayerBase::stop() {
    if (playerStop() == NO_ERROR) {
    ALOGD("PlayerBase::stop() from IPlayer");
        servicePlayerEvent(PLAYER_STATE_STOPPED);
    } else {
        ALOGD("PlayerBase::stop() no AudioTrack to stop from IPlayer");
    }
    (void)stopWithStatus();
}

void PlayerBase::setVolume(float vol) {
    ALOGD("PlayerBase::setVolume() from IPlayer");
    {
        Mutex::Autolock _l(mSettingsLock);
        mVolumeMultiplierL = vol;
        mVolumeMultiplierR = vol;
    }
    if (playerSetVolume() == NO_ERROR) {
        ALOGD("PlayerBase::setVolume() from IPlayer");
    } else {
        ALOGD("PlayerBase::setVolume() no AudioTrack for volume control from IPlayer");
    status_t status = playerSetVolume();
    if (status != NO_ERROR) {
        ALOGW("PlayerBase::setVolume() error %d", status);
    }
}

void PlayerBase::setPan(float pan) {
    ALOGD("PlayerBase::setPan() from IPlayer");
    {
        Mutex::Autolock _l(mSettingsLock);
        pan = min(max(-1.0f, pan), 1.0f);
@@ -145,10 +159,9 @@ void PlayerBase::setPan(float pan) {
            mPanMultiplierR = 1.0f + pan;
        }
    }
    if (playerSetVolume() == NO_ERROR) {
        ALOGD("PlayerBase::setPan() from IPlayer");
    } else {
        ALOGD("PlayerBase::setPan() no AudioTrack for volume control from IPlayer");
    status_t status = playerSetVolume();
    if (status != NO_ERROR) {
        ALOGW("PlayerBase::setPan() error %d", status);
    }
}

+2 −0
Original line number Diff line number Diff line
@@ -48,6 +48,8 @@ public:


            status_t startWithStatus();
            status_t pauseWithStatus();
            status_t stopWithStatus();

            //FIXME temporary method while some player state is outside of this class
            void reportEvent(player_state_t event);
Loading