AudioStreamRecord.cpp revision 35e80f34a9649752fceafa53e2094cd8eda50a0a
1e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk/* 2e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk * Copyright 2016 The Android Open Source Project 3e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk * 4e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk * Licensed under the Apache License, Version 2.0 (the "License"); 5e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk * you may not use this file except in compliance with the License. 6e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk * You may obtain a copy of the License at 7e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk * 8e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk * http://www.apache.org/licenses/LICENSE-2.0 9e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk * 10e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk * Unless required by applicable law or agreed to in writing, software 11e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk * distributed under the License is distributed on an "AS IS" BASIS, 12e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk * See the License for the specific language governing permissions and 14e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk * limitations under the License. 15e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk */ 16e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 17e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk#define LOG_TAG "AudioStreamRecord" 18e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk//#define LOG_NDEBUG 0 19e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk#include <utils/Log.h> 20e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 21e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk#include <stdint.h> 22e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk#include <utils/String16.h> 23e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk#include <media/AudioRecord.h> 245ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk#include <aaudio/AAudio.h> 25e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 26e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk#include "AudioClock.h" 27e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk#include "AudioStreamRecord.h" 2835e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk#include "utility/AAudioUtilities.h" 29e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 30e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burkusing namespace android; 315ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkusing namespace aaudio; 32e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 33e1ce491a25faf06fdeab00dd938515f71f28b095Phil BurkAudioStreamRecord::AudioStreamRecord() 34e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk : AudioStream() 35e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 36e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 37e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 38e1ce491a25faf06fdeab00dd938515f71f28b095Phil BurkAudioStreamRecord::~AudioStreamRecord() 39e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 405ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk const aaudio_stream_state_t state = getState(); 415ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk bool bad = !(state == AAUDIO_STREAM_STATE_UNINITIALIZED || state == AAUDIO_STREAM_STATE_CLOSED); 42e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk ALOGE_IF(bad, "stream not closed, in state %d", state); 43e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 44e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 455ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkaaudio_result_t AudioStreamRecord::open(const AudioStreamBuilder& builder) 46e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 475ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk aaudio_result_t result = AAUDIO_OK; 48e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 49e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk result = AudioStream::open(builder); 505ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk if (result != AAUDIO_OK) { 51e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk return result; 52e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 53e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 54e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk // Try to create an AudioRecord 55e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 56e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk // TODO Support UNSPECIFIED in AudioTrack. For now, use stereo if unspecified. 575ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk int32_t samplesPerFrame = (getSamplesPerFrame() == AAUDIO_UNSPECIFIED) 58e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk ? 2 : getSamplesPerFrame(); 59e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk audio_channel_mask_t channelMask = audio_channel_in_mask_from_count(samplesPerFrame); 60e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 61d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk AudioRecord::callback_t callback = nullptr; 62e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk audio_input_flags_t flags = (audio_input_flags_t) AUDIO_INPUT_FLAG_NONE; 63e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 643df348fbaca567ca891503213ff8c344a1ea2e05Phil Burk size_t frameCount = (builder.getBufferCapacity() == AAUDIO_UNSPECIFIED) ? 0 653df348fbaca567ca891503213ff8c344a1ea2e05Phil Burk : builder.getBufferCapacity(); 66e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk // TODO implement an unspecified Android format then use that. 675ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk audio_format_t format = (getFormat() == AAUDIO_UNSPECIFIED) 68e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk ? AUDIO_FORMAT_PCM_FLOAT 695ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk : AAudioConvert_aaudioToAndroidDataFormat(getFormat()); 70e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 71e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk mAudioRecord = new AudioRecord( 72e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk AUDIO_SOURCE_DEFAULT, 73e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk getSampleRate(), 74e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk format, 75e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk channelMask, 76e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk mOpPackageName, // const String16& opPackageName TODO does not compile 773df348fbaca567ca891503213ff8c344a1ea2e05Phil Burk frameCount, 78e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk callback, 79d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk nullptr, // void* user = nullptr, 80e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 0, // uint32_t notificationFrames = 0, 81e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk AUDIO_SESSION_ALLOCATE, 82e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk AudioRecord::TRANSFER_DEFAULT, 83e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk flags 843df348fbaca567ca891503213ff8c344a1ea2e05Phil Burk // int uid = -1, 853df348fbaca567ca891503213ff8c344a1ea2e05Phil Burk // pid_t pid = -1, 863df348fbaca567ca891503213ff8c344a1ea2e05Phil Burk // const audio_attributes_t* pAttributes = nullptr 873df348fbaca567ca891503213ff8c344a1ea2e05Phil Burk ); 88e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 89e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk // Did we get a valid track? 90e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk status_t status = mAudioRecord->initCheck(); 91e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk if (status != OK) { 92e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk close(); 93e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk ALOGE("AudioStreamRecord::open(), initCheck() returned %d", status); 945ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAudioConvert_androidToAAudioResult(status); 95e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 96e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 97e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk // Get the actual rate. 98e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk setSampleRate(mAudioRecord->getSampleRate()); 99e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk setSamplesPerFrame(mAudioRecord->channelCount()); 1005ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk setFormat(AAudioConvert_androidToAAudioDataFormat(mAudioRecord->format())); 101e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 1025ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk setState(AAUDIO_STREAM_STATE_OPEN); 103e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 1045ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_OK; 105e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 106e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 1075ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkaaudio_result_t AudioStreamRecord::close() 108e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 109e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk // TODO add close() or release() to AudioRecord API then call it from here 1105ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk if (getState() != AAUDIO_STREAM_STATE_CLOSED) { 111e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk mAudioRecord.clear(); 1125ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk setState(AAUDIO_STREAM_STATE_CLOSED); 113e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 1145ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_OK; 115e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 116e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 1175ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkaaudio_result_t AudioStreamRecord::requestStart() 118e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 119d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk if (mAudioRecord.get() == nullptr) { 1205ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_ERROR_INVALID_STATE; 121e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 122e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk // Get current position so we can detect when the track is playing. 123e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk status_t err = mAudioRecord->getPosition(&mPositionWhenStarting); 124e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk if (err != OK) { 1255ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAudioConvert_androidToAAudioResult(err); 126e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 127e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk err = mAudioRecord->start(); 128e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk if (err != OK) { 1295ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAudioConvert_androidToAAudioResult(err); 130e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } else { 1315ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk setState(AAUDIO_STREAM_STATE_STARTING); 132e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 1335ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_OK; 134e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 135e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 1365ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkaaudio_result_t AudioStreamRecord::requestPause() 137e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 1385ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_ERROR_UNIMPLEMENTED; 139e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 140e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 1415ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkaaudio_result_t AudioStreamRecord::requestFlush() { 1425ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_ERROR_UNIMPLEMENTED; 143e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 144e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 1455ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkaaudio_result_t AudioStreamRecord::requestStop() { 146d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk if (mAudioRecord.get() == nullptr) { 1475ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_ERROR_INVALID_STATE; 148e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 1495ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk setState(AAUDIO_STREAM_STATE_STOPPING); 150e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk mAudioRecord->stop(); 1515ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_OK; 152e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 153e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 1545ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkaaudio_result_t AudioStreamRecord::updateState() 155e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 1565ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk aaudio_result_t result = AAUDIO_OK; 1575ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk aaudio_wrapping_frames_t position; 158e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk status_t err; 159e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk switch (getState()) { 160e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk // TODO add better state visibility to AudioRecord 1615ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk case AAUDIO_STREAM_STATE_STARTING: 162e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk err = mAudioRecord->getPosition(&position); 163e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk if (err != OK) { 1645ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk result = AAudioConvert_androidToAAudioResult(err); 165e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } else if (position != mPositionWhenStarting) { 1665ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk setState(AAUDIO_STREAM_STATE_STARTED); 167e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 168e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk break; 1695ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk case AAUDIO_STREAM_STATE_STOPPING: 170e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk if (mAudioRecord->stopped()) { 1715ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk setState(AAUDIO_STREAM_STATE_STOPPED); 172e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 173e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk break; 174e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk default: 175e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk break; 176e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 177e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk return result; 178e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 179e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 1805ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkaaudio_result_t AudioStreamRecord::read(void *buffer, 1813316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk int32_t numFrames, 1823316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk int64_t timeoutNanoseconds) 183e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 1843316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk int32_t bytesPerFrame = getBytesPerFrame(); 1853316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk int32_t numBytes; 1865ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk aaudio_result_t result = AAudioConvert_framesToBytes(numFrames, bytesPerFrame, &numBytes); 1875ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk if (result != AAUDIO_OK) { 188e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk return result; 189e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 190e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 191e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk // TODO add timeout to AudioRecord 192e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk bool blocking = (timeoutNanoseconds > 0); 193e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk ssize_t bytesRead = mAudioRecord->read(buffer, numBytes, blocking); 194e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk if (bytesRead == WOULD_BLOCK) { 195e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk return 0; 196e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } else if (bytesRead < 0) { 1975ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAudioConvert_androidToAAudioResult(bytesRead); 198e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 1993316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk int32_t framesRead = (int32_t)(bytesRead / bytesPerFrame); 2005ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return (aaudio_result_t) framesRead; 201e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 202e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 2033316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burkaaudio_result_t AudioStreamRecord::setBufferSize(int32_t requestedFrames) 204e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 2053316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk return getBufferSize(); 206e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 207e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 2083316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burkint32_t AudioStreamRecord::getBufferSize() const 209e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 210e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk return getBufferCapacity(); // TODO implement in AudioRecord? 211e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 212e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 2133316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burkint32_t AudioStreamRecord::getBufferCapacity() const 214e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 2153316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk return static_cast<int32_t>(mAudioRecord->frameCount()); 216e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 217e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 218e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burkint32_t AudioStreamRecord::getXRunCount() const 219e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 2205ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_ERROR_UNIMPLEMENTED; // TODO implement when AudioRecord supports it 221e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 222e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 2233316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burkint32_t AudioStreamRecord::getFramesPerBurst() const 224e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 225e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk return 192; // TODO add query to AudioRecord.cpp 226e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 227e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 22835e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burkaaudio_result_t AudioStreamRecord::getTimestamp(clockid_t clockId, 22935e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk int64_t *framePosition, 23035e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk int64_t *timeNanoseconds) { 23135e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk ExtendedTimestamp extendedTimestamp; 23235e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk status_t status = mAudioRecord->getTimestamp(&extendedTimestamp); 23335e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk if (status != NO_ERROR) { 23435e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk return AAudioConvert_androidToAAudioResult(status); 23535e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk } 23635e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk // TODO Merge common code into AudioStreamLegacy after rebasing. 23735e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk int timebase; 23835e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk switch(clockId) { 23935e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk case CLOCK_BOOTTIME: 24035e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk timebase = ExtendedTimestamp::TIMEBASE_BOOTTIME; 24135e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk break; 24235e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk case CLOCK_MONOTONIC: 24335e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk timebase = ExtendedTimestamp::TIMEBASE_MONOTONIC; 24435e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk break; 24535e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk default: 24635e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk ALOGE("getTimestamp() - Unrecognized clock type %d", (int) clockId); 24735e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk return AAUDIO_ERROR_UNEXPECTED_VALUE; 24835e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk break; 24935e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk } 25035e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk status = extendedTimestamp.getBestTimestamp(framePosition, timeNanoseconds, timebase); 25135e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk return AAudioConvert_androidToAAudioResult(status); 25235e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk} 253