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

Commit ebaaeedf authored by Atneya Nair's avatar Atneya Nair Committed by Android (Google) Code Review
Browse files

Merge "Modify AAudio for new AudioTrack callback format"

parents 7eb42ea6 7daa4f99
Loading
Loading
Loading
Loading
+56 −72
Original line number Diff line number Diff line
@@ -37,15 +37,6 @@ AudioStreamLegacy::AudioStreamLegacy()
        : AudioStream() {
}

// Called from AudioTrack.cpp or AudioRecord.cpp
static void AudioStreamLegacy_callback(int event, void* userData, void *info) {
    AudioStreamLegacy *streamLegacy = (AudioStreamLegacy *) userData;
    streamLegacy->processCallback(event, info);
}

aaudio_legacy_callback_t AudioStreamLegacy::getLegacyCallback() {
    return AudioStreamLegacy_callback;
}

aaudio_data_callback_result_t AudioStreamLegacy::callDataCallbackFrames(uint8_t *buffer,
                                                                        int32_t numFrames) {
@@ -73,51 +64,55 @@ int32_t AudioStreamLegacy::onProcessFixedBlock(uint8_t *buffer, int32_t numBytes
    return (int32_t) callDataCallbackFrames(buffer, numFrames);
}

void AudioStreamLegacy::processCallbackCommon(aaudio_callback_operation_t opcode, void *info) {
    aaudio_data_callback_result_t callbackResult;

void AudioStreamLegacy::onNewIAudioTrack() {
    ALOGD("%s stream disconnected", __func__);
    forceDisconnect();
    mCallbackEnabled.store(false);
}

size_t AudioStreamLegacy::onMoreData(const android::AudioTrack::Buffer& buffer) {
    // This illegal size can be used to tell AudioRecord or AudioTrack to stop calling us.
    // This takes advantage of them killing the stream when they see a size out of range.
    // That is an undocumented behavior.
    // TODO add to API in AudioRecord and AudioTrack
    const size_t SIZE_STOP_CALLBACKS = SIZE_MAX;

    switch (opcode) {
        case AAUDIO_CALLBACK_OPERATION_PROCESS_DATA: {
    aaudio_data_callback_result_t callbackResult;
    (void) checkForDisconnectRequest(true);

    // Note that this code assumes an AudioTrack::Buffer is the same as
    // AudioRecord::Buffer
    // TODO define our own AudioBuffer and pass it from the subclasses.
            AudioTrack::Buffer *audioBuffer = static_cast<AudioTrack::Buffer *>(info);
    size_t written = buffer.size;
    if (getState() == AAUDIO_STREAM_STATE_DISCONNECTED) {
                ALOGW("processCallbackCommon() data, stream disconnected");
        ALOGW("%s() data, stream disconnected", __func__);
        // This will kill the stream and prevent it from being restarted.
        // That is OK because the stream is disconnected.
                audioBuffer->size = SIZE_STOP_CALLBACKS;
        written = SIZE_STOP_CALLBACKS;
    } else if (!mCallbackEnabled.load()) {
                ALOGW("processCallbackCommon() no data because callback disabled, set size=0");
        ALOGW("%s() no data because callback disabled, set size=0", __func__);
        // Do NOT use SIZE_STOP_CALLBACKS here because that will kill the stream and
        // prevent it from being restarted. This can occur because of a race condition
        // caused by Legacy callbacks running after the track is "stopped".
                audioBuffer->size = 0;
        written = 0;
    } else {
                if (audioBuffer->frameCount == 0) {
                    ALOGW("processCallbackCommon() data, frameCount is zero");
                    return;
        if (buffer.frameCount == 0) {
            ALOGW("%s() data, frameCount is zero", __func__);
            return written;
        }

        // If the caller specified an exact size then use a block size adapter.
        if (mBlockAdapter != nullptr) {
                    int32_t byteCount = audioBuffer->frameCount * getBytesPerDeviceFrame();
            int32_t byteCount = buffer.frameCount * getBytesPerDeviceFrame();
            callbackResult = mBlockAdapter->processVariableBlock(
                            (uint8_t *) audioBuffer->raw, byteCount);
                    static_cast<uint8_t*>(buffer.raw), byteCount);
        } else {
            // Call using the AAudio callback interface.
                    callbackResult = callDataCallbackFrames((uint8_t *)audioBuffer->raw,
                                                            audioBuffer->frameCount);
            callbackResult = callDataCallbackFrames(static_cast<uint8_t *>(buffer.raw),
                                                    buffer.frameCount);
        }
        if (callbackResult == AAUDIO_CALLBACK_RESULT_CONTINUE) {
                    audioBuffer->size = audioBuffer->frameCount * getBytesPerDeviceFrame();
            written = buffer.frameCount * getBytesPerDeviceFrame();
        } else {
            if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
                ALOGD("%s() callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
@@ -125,7 +120,7 @@ void AudioStreamLegacy::processCallbackCommon(aaudio_callback_operation_t opcode
                ALOGW("%s() callback returned invalid result = %d",
                      __func__, callbackResult);
            }
                    audioBuffer->size = 0;
            written = 0;
            systemStopInternal();
            // Disable the callback just in case the system keeps trying to call us.
            mCallbackEnabled.store(false);
@@ -136,20 +131,9 @@ void AudioStreamLegacy::processCallbackCommon(aaudio_callback_operation_t opcode
            mCallbackEnabled.store(false);
        }
    }
    return written;
}
            break;

        // Stream got rerouted so we disconnect.
        case AAUDIO_CALLBACK_OPERATION_DISCONNECTED:
            ALOGD("processCallbackCommon() stream disconnected");
            forceDisconnect();
            mCallbackEnabled.store(false);
            break;

        default:
            break;
    }
}

aaudio_result_t AudioStreamLegacy::checkForDisconnectRequest(bool errorCallbackEnabled) {
    if (mRequestDisconnect.isRequested()) {
+6 −10
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#define LEGACY_AUDIO_STREAM_LEGACY_H

#include <media/AudioTimestamp.h>
#include <media/AudioTrack.h>
#include <media/AudioSystem.h>

#include <aaudio/AAudio.h>
@@ -30,8 +31,6 @@
namespace aaudio {


typedef void (*aaudio_legacy_callback_t)(int event, void* user, void *info);

enum {
    /**
     * Request that the callback function should fill the data buffer of an output stream,
@@ -56,21 +55,17 @@ enum {
typedef int32_t aaudio_callback_operation_t;


class AudioStreamLegacy : public AudioStream, public FixedBlockProcessor {
class AudioStreamLegacy : public AudioStream,
                          public FixedBlockProcessor,
                          protected android::AudioTrack::IAudioTrackCallback {
public:
    AudioStreamLegacy();

    virtual ~AudioStreamLegacy() = default;

    aaudio_legacy_callback_t getLegacyCallback();

    int32_t callDataCallbackFrames(uint8_t *buffer, int32_t numFrames);

    // This is public so it can be called from the C callback function.
    // This is called from the AudioTrack/AudioRecord client.
    virtual void processCallback(int event, void *info) = 0;

    void processCallbackCommon(aaudio_callback_operation_t opcode, void *info);

    // Implement FixedBlockProcessor
    int32_t onProcessFixedBlock(uint8_t *buffer, int32_t numBytes) override;
@@ -86,7 +81,8 @@ public:
    }

protected:

    size_t onMoreData(const android::AudioTrack::Buffer& buffer) override;
    void onNewIAudioTrack() override;
    aaudio_result_t getBestTimestamp(clockid_t clockId,
                                     int64_t *framePosition,
                                     int64_t *timeNanoseconds,
+10 −5
Original line number Diff line number Diff line
@@ -37,6 +37,10 @@ using android::content::AttributionSourceState;
using namespace android;
using namespace aaudio;

static void sCallbackWrapper(int event, void* userData, void* info) {
    static_cast<AudioStreamRecord*>(userData)->processCallback(event, info);
}

AudioStreamRecord::AudioStreamRecord()
    : AudioStreamLegacy()
    , mFixedBlockWriter(*this)
@@ -129,7 +133,7 @@ aaudio_result_t AudioStreamRecord::open(const AudioStreamBuilder& builder)
    AudioRecord::transfer_type streamTransferType = AudioRecord::transfer_type::TRANSFER_SYNC;
    if (builder.getDataCallbackProc() != nullptr) {
        streamTransferType = AudioRecord::transfer_type::TRANSFER_CALLBACK;
        callback = getLegacyCallback();
        callback = sCallbackWrapper;
        callbackData = this;
    }
    mCallbackBufferSize = builder.getFramesPerDataCallback();
@@ -353,14 +357,15 @@ const void * AudioStreamRecord::maybeConvertDeviceData(const void *audioData, in
void AudioStreamRecord::processCallback(int event, void *info) {
    switch (event) {
        case AudioRecord::EVENT_MORE_DATA:
            processCallbackCommon(AAUDIO_CALLBACK_OPERATION_PROCESS_DATA, info);
        {
            AudioTrack::Buffer *audioBuffer = static_cast<AudioTrack::Buffer *>(info);
            audioBuffer->size = onMoreData(*audioBuffer);
            break;

        }
            // Stream got rerouted so we disconnect.
        case AudioRecord::EVENT_NEW_IAUDIORECORD:
            processCallbackCommon(AAUDIO_CALLBACK_OPERATION_DISCONNECTED, info);
            onNewIAudioTrack();
            break;

        default:
            break;
    }
+3 −1
Original line number Diff line number Diff line
@@ -65,7 +65,9 @@ public:
    }

    // This is public so it can be called from the C callback function.
    void processCallback(int event, void *info) override;
    void processCallback(int event, void *info);

    void processCallbackRecord(aaudio_callback_operation_t opcode, void *info);

    int64_t incrementClientFrameCounter(int32_t frames) override {
        return incrementFramesRead(frames);
+13 −28
Original line number Diff line number Diff line
@@ -103,14 +103,12 @@ aaudio_result_t AudioStreamTrack::open(const AudioStreamBuilder& builder)
            : getFormat();

    // Setup the callback if there is one.
    AudioTrack::legacy_callback_t callback = nullptr;
    void *callbackData = nullptr;
    wp<AudioTrack::IAudioTrackCallback> callback;
    // Note that TRANSFER_SYNC does not allow FAST track
    AudioTrack::transfer_type streamTransferType = AudioTrack::transfer_type::TRANSFER_SYNC;
    if (builder.getDataCallbackProc() != nullptr) {
        streamTransferType = AudioTrack::transfer_type::TRANSFER_CALLBACK;
        callback = getLegacyCallback();
        callbackData = this;
        callback = wp<AudioTrack::IAudioTrackCallback>::fromExisting(this);

        // If the total buffer size is unspecified then base the size on the burst size.
        if (frameCount == 0
@@ -157,7 +155,6 @@ aaudio_result_t AudioStreamTrack::open(const AudioStreamBuilder& builder)
            frameCount,
            flags,
            callback,
            callbackData,
            notificationFrames,
            nullptr,       // DEFAULT sharedBuffer*/,
            false,   // DEFAULT threadCanCallJava
@@ -293,15 +290,9 @@ void AudioStreamTrack::close_l() {
    AudioStream::close_l();
}

void AudioStreamTrack::processCallback(int event, void *info) {

    switch (event) {
        case AudioTrack::EVENT_MORE_DATA:
            processCallbackCommon(AAUDIO_CALLBACK_OPERATION_PROCESS_DATA, info);
            break;

void AudioStreamTrack::onNewIAudioTrack() {
    // Stream got rerouted so we disconnect.
        case AudioTrack::EVENT_NEW_IAUDIOTRACK:
    // request stream disconnect if the restored AudioTrack has properties not matching
    // what was requested initially
    if (mAudioTrack->channelCount() != getSamplesPerFrame()
@@ -310,14 +301,8 @@ void AudioStreamTrack::processCallback(int event, void *info) {
          || mAudioTrack->getRoutedDeviceId() != getDeviceId()
          || getBufferCapacityFromDevice() != getBufferCapacity()
          || getFramesPerBurstFromDevice() != getFramesPerBurst()) {
                processCallbackCommon(AAUDIO_CALLBACK_OPERATION_DISCONNECTED, info);
            }
            break;

        default:
            break;
        AudioStreamLegacy::onNewIAudioTrack();
    }
    return;
}

aaudio_result_t AudioStreamTrack::requestStart_l() {
Loading