187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk/* 287c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk * Copyright (C) 2017 The Android Open Source Project 387c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk * 487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk * Licensed under the Apache License, Version 2.0 (the "License"); 587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk * you may not use this file except in compliance with the License. 687c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk * You may obtain a copy of the License at 787c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk * 887c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk * http://www.apache.org/licenses/LICENSE-2.0 987c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk * 1087c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk * Unless required by applicable law or agreed to in writing, software 1187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk * distributed under the License is distributed on an "AS IS" BASIS, 1287c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1387c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk * See the License for the specific language governing permissions and 1487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk * limitations under the License. 1587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk */ 1687c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 1787c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk#define LOG_TAG "AAudio" 1887c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk//#define LOG_NDEBUG 0 1987c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk#include <utils/Log.h> 2087c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 2187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk#include <aaudio/AAudio.h> 2287c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 2387c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk#include "client/AudioStreamInternalCapture.h" 2487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk#include "utility/AudioClock.h" 2587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 2687c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burkusing android::WrappingBuffer; 2787c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 2887c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burkusing namespace aaudio; 2987c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 3087c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil BurkAudioStreamInternalCapture::AudioStreamInternalCapture(AAudioServiceInterface &serviceInterface, 3187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk bool inService) 3287c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk : AudioStreamInternal(serviceInterface, inService) { 3387c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 3487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk} 3587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 3687c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil BurkAudioStreamInternalCapture::~AudioStreamInternalCapture() {} 3787c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 3887c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 3987c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk// Write the data, block if needed and timeoutMillis > 0 4087c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burkaaudio_result_t AudioStreamInternalCapture::read(void *buffer, int32_t numFrames, 4187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk int64_t timeoutNanoseconds) 4287c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk{ 4387c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk return processData(buffer, numFrames, timeoutNanoseconds); 4487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk} 4587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 4687c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk// Read as much data as we can without blocking. 4787c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burkaaudio_result_t AudioStreamInternalCapture::processDataNow(void *buffer, int32_t numFrames, 4887c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk int64_t currentNanoTime, int64_t *wakeTimePtr) { 4987c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk aaudio_result_t result = processCommands(); 5087c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk if (result != AAUDIO_OK) { 5187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk return result; 5287c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk } 5387c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 5487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk if (mAudioEndpoint.isFreeRunning()) { 5587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk //ALOGD("AudioStreamInternalCapture::processDataNow() - update remote counter"); 5687c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk // Update data queue based on the timing model. 5787c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk int64_t estimatedRemoteCounter = mClockModel.convertTimeToPosition(currentNanoTime); 5887c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk // TODO refactor, maybe use setRemoteCounter() 5987c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk mAudioEndpoint.setDataWriteCounter(estimatedRemoteCounter); 6087c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk } 6187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 6287c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk // If the write index passed the read index then consider it an overrun. 6387c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk if (mAudioEndpoint.getEmptyFramesAvailable() < 0) { 6487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk mXRunCount++; 6587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk } 6687c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 6787c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk // Read some data from the buffer. 6887c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk //ALOGD("AudioStreamInternalCapture::processDataNow() - readNowWithConversion(%d)", numFrames); 6987c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk int32_t framesProcessed = readNowWithConversion(buffer, numFrames); 7087c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk //ALOGD("AudioStreamInternalCapture::processDataNow() - tried to read %d frames, read %d", 7187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk // numFrames, framesProcessed); 7287c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 7387c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk // Calculate an ideal time to wake up. 7487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk if (wakeTimePtr != nullptr && framesProcessed >= 0) { 7587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk // By default wake up a few milliseconds from now. // TODO review 7687c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk int64_t wakeTime = currentNanoTime + (1 * AAUDIO_NANOS_PER_MILLISECOND); 7787c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk aaudio_stream_state_t state = getState(); 7887c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk //ALOGD("AudioStreamInternalCapture::processDataNow() - wakeTime based on %s", 7987c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk // AAudio_convertStreamStateToText(state)); 8087c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk switch (state) { 8187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk case AAUDIO_STREAM_STATE_OPEN: 8287c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk case AAUDIO_STREAM_STATE_STARTING: 8387c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk break; 8487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk case AAUDIO_STREAM_STATE_STARTED: // When do we expect the next read burst to occur? 8587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk { 8687c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk uint32_t burstSize = mFramesPerBurst; 8787c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk if (burstSize < 32) { 8887c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk burstSize = 32; // TODO review 8987c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk } 9087c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 9187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk uint64_t nextReadPosition = mAudioEndpoint.getDataWriteCounter() + burstSize; 9287c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk wakeTime = mClockModel.convertPositionToTime(nextReadPosition); 9387c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk } 9487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk break; 9587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk default: 9687c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk break; 9787c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk } 9887c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk *wakeTimePtr = wakeTime; 9987c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 10087c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk } 10187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk// ALOGD("AudioStreamInternalCapture::readNow finished: now = %llu, read# = %llu, wrote# = %llu", 10287c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk// (unsigned long long)currentNanoTime, 10387c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk// (unsigned long long)mAudioEndpoint.getDataReadCounter(), 10487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk// (unsigned long long)mAudioEndpoint.getDownDataWriteCounter()); 10587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk return framesProcessed; 10687c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk} 10787c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 10887c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burkaaudio_result_t AudioStreamInternalCapture::readNowWithConversion(void *buffer, 10987c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk int32_t numFrames) { 11087c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk // ALOGD("AudioStreamInternalCapture::readNowWithConversion(%p, %d)", 11187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk // buffer, numFrames); 11287c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk WrappingBuffer wrappingBuffer; 11387c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk uint8_t *destination = (uint8_t *) buffer; 11487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk int32_t framesLeft = numFrames; 11587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 11687c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk mAudioEndpoint.getFullFramesAvailable(&wrappingBuffer); 11787c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 11887c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk // Read data in one or two parts. 11987c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk for (int partIndex = 0; framesLeft > 0 && partIndex < WrappingBuffer::SIZE; partIndex++) { 12087c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk int32_t framesToProcess = framesLeft; 12187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk int32_t framesAvailable = wrappingBuffer.numFrames[partIndex]; 12287c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk if (framesAvailable <= 0) break; 12387c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 12487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk if (framesToProcess > framesAvailable) { 12587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk framesToProcess = framesAvailable; 12687c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk } 12787c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 12887c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk int32_t numBytes = getBytesPerFrame() * framesToProcess; 12987c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk int32_t numSamples = framesToProcess * getSamplesPerFrame(); 13087c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 13187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk // TODO factor this out into a utility function 13287c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk if (mDeviceFormat == getFormat()) { 13387c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk memcpy(destination, wrappingBuffer.data[partIndex], numBytes); 13487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk } else if (mDeviceFormat == AAUDIO_FORMAT_PCM_I16 13587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk && getFormat() == AAUDIO_FORMAT_PCM_FLOAT) { 13687c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk AAudioConvert_pcm16ToFloat( 13787c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk (const int16_t *) wrappingBuffer.data[partIndex], 13887c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk (float *) destination, 13987c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk numSamples, 14087c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 1.0f); 14187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk } else if (mDeviceFormat == AAUDIO_FORMAT_PCM_FLOAT 14287c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk && getFormat() == AAUDIO_FORMAT_PCM_I16) { 14387c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk AAudioConvert_floatToPcm16( 14487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk (const float *) wrappingBuffer.data[partIndex], 14587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk (int16_t *) destination, 14687c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk numSamples, 14787c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 1.0f); 14887c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk } else { 14987c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk ALOGE("Format conversion not supported!"); 15087c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk return AAUDIO_ERROR_INVALID_FORMAT; 15187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk } 15287c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk destination += numBytes; 15387c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk framesLeft -= framesToProcess; 15487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk } 15587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 15687c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk int32_t framesProcessed = numFrames - framesLeft; 15787c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk mAudioEndpoint.advanceReadIndex(framesProcessed); 15887c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk incrementFramesRead(framesProcessed); 15987c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 16087c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk //ALOGD("AudioStreamInternalCapture::readNowWithConversion() returns %d", framesProcessed); 16187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk return framesProcessed; 16287c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk} 16387c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 16487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burkint64_t AudioStreamInternalCapture::getFramesWritten() 16587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk{ 16687c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk int64_t frames = 16787c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk mClockModel.convertTimeToPosition(AudioClock::getNanoseconds()) 16887c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk + mFramesOffsetFromService; 16987c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk // Prevent retrograde motion. 17087c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk if (frames < mLastFramesWritten) { 17187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk frames = mLastFramesWritten; 17287c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk } else { 17387c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk mLastFramesWritten = frames; 17487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk } 17587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk //ALOGD("AudioStreamInternalCapture::getFramesWritten() returns %lld", (long long)frames); 17687c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk return frames; 17787c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk} 17887c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 17987c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burkint64_t AudioStreamInternalCapture::getFramesRead() 18087c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk{ 18187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk int64_t frames = mAudioEndpoint.getDataWriteCounter() 18287c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk + mFramesOffsetFromService; 18387c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk //ALOGD("AudioStreamInternalCapture::getFramesRead() returns %lld", (long long)frames); 18487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk return frames; 18587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk} 18687c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 18787c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk// Read data from the stream and pass it to the callback for processing. 18887c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burkvoid *AudioStreamInternalCapture::callbackLoop() { 18987c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk aaudio_result_t result = AAUDIO_OK; 19087c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk aaudio_data_callback_result_t callbackResult = AAUDIO_CALLBACK_RESULT_CONTINUE; 19187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk AAudioStream_dataCallback appCallback = getDataCallbackProc(); 19287c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk if (appCallback == nullptr) return NULL; 19387c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 19487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk // result might be a frame count 19587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk while (mCallbackEnabled.load() && isActive() && (result >= 0)) { 19687c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 19787c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk // Read audio data from stream. 19887c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk int64_t timeoutNanos = calculateReasonableTimeout(mCallbackFrames); 19987c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 20087c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk // This is a BLOCKING READ! 20187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk result = read(mCallbackBuffer, mCallbackFrames, timeoutNanos); 20287c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk if ((result != mCallbackFrames)) { 20387c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk ALOGE("AudioStreamInternalCapture(): callbackLoop: read() returned %d", result); 20487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk if (result >= 0) { 20587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk // Only read some of the frames requested. Must have timed out. 20687c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk result = AAUDIO_ERROR_TIMEOUT; 20787c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk } 20887c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk AAudioStream_errorCallback errorCallback = getErrorCallbackProc(); 20987c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk if (errorCallback != nullptr) { 21087c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk (*errorCallback)( 21187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk (AAudioStream *) this, 21287c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk getErrorCallbackUserData(), 21387c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk result); 21487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk } 21587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk break; 21687c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk } 21787c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 21887c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk // Call application using the AAudio callback interface. 21987c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk callbackResult = (*appCallback)( 22087c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk (AAudioStream *) this, 22187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk getDataCallbackUserData(), 22287c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk mCallbackBuffer, 22387c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk mCallbackFrames); 22487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 22587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) { 22687c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk ALOGD("AudioStreamInternalCapture(): callback returned AAUDIO_CALLBACK_RESULT_STOP"); 22787c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk break; 22887c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk } 22987c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk } 23087c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk 23187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk ALOGD("AudioStreamInternalCapture(): callbackLoop() exiting, result = %d, isActive() = %d", 23287c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk result, (int) isActive()); 23387c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk return NULL; 23487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk} 235