AudioStreamRecord.cpp revision b588402d48c9634fa72e7e13ca6d6f2a0766cb98
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" 27e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#include "legacy/AudioStreamLegacy.h" 28e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#include "legacy/AudioStreamRecord.h" 29e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#include "utility/FixedBlockWriter.h" 30e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 31e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burkusing namespace android; 325ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkusing namespace aaudio; 33e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 34e1ce491a25faf06fdeab00dd938515f71f28b095Phil BurkAudioStreamRecord::AudioStreamRecord() 35e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk : AudioStreamLegacy() 36e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk , mFixedBlockWriter(*this) 37e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 38e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 39e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 40e1ce491a25faf06fdeab00dd938515f71f28b095Phil BurkAudioStreamRecord::~AudioStreamRecord() 41e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 425ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk const aaudio_stream_state_t state = getState(); 435ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk bool bad = !(state == AAUDIO_STREAM_STATE_UNINITIALIZED || state == AAUDIO_STREAM_STATE_CLOSED); 44e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk ALOGE_IF(bad, "stream not closed, in state %d", state); 45e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 46e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 475ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkaaudio_result_t AudioStreamRecord::open(const AudioStreamBuilder& builder) 48e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 495ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk aaudio_result_t result = AAUDIO_OK; 50e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 51e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk result = AudioStream::open(builder); 525ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk if (result != AAUDIO_OK) { 53e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk return result; 54e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 55e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 56e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk // Try to create an AudioRecord 57e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 58e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk // TODO Support UNSPECIFIED in AudioTrack. For now, use stereo if unspecified. 595ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk int32_t samplesPerFrame = (getSamplesPerFrame() == AAUDIO_UNSPECIFIED) 60e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk ? 2 : getSamplesPerFrame(); 61e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk audio_channel_mask_t channelMask = audio_channel_in_mask_from_count(samplesPerFrame); 62e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 63e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk audio_input_flags_t flags = (audio_input_flags_t) AUDIO_INPUT_FLAG_NONE; 64e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 653df348fbaca567ca891503213ff8c344a1ea2e05Phil Burk size_t frameCount = (builder.getBufferCapacity() == AAUDIO_UNSPECIFIED) ? 0 663df348fbaca567ca891503213ff8c344a1ea2e05Phil Burk : builder.getBufferCapacity(); 67e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk // TODO implement an unspecified Android format then use that. 685ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk audio_format_t format = (getFormat() == AAUDIO_UNSPECIFIED) 69e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk ? AUDIO_FORMAT_PCM_FLOAT 705ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk : AAudioConvert_aaudioToAndroidDataFormat(getFormat()); 71e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 72e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk // Setup the callback if there is one. 73e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk AudioRecord::callback_t callback = nullptr; 74e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk void *callbackData = nullptr; 75e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk AudioRecord::transfer_type streamTransferType = AudioRecord::transfer_type::TRANSFER_SYNC; 76e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk if (builder.getDataCallbackProc() != nullptr) { 77e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk streamTransferType = AudioRecord::transfer_type::TRANSFER_CALLBACK; 78e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk callback = getLegacyCallback(); 79e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk callbackData = this; 80e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk } 81e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk mCallbackBufferSize = builder.getFramesPerDataCallback(); 82e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 83e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk mAudioRecord = new AudioRecord( 84e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk AUDIO_SOURCE_DEFAULT, 85e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk getSampleRate(), 86e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk format, 87e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk channelMask, 88e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk mOpPackageName, // const String16& opPackageName TODO does not compile 893df348fbaca567ca891503213ff8c344a1ea2e05Phil Burk frameCount, 90e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk callback, 91e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk callbackData, 92e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 0, // uint32_t notificationFrames = 0, 93e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk AUDIO_SESSION_ALLOCATE, 94e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk streamTransferType, 95e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk flags 963df348fbaca567ca891503213ff8c344a1ea2e05Phil Burk // int uid = -1, 973df348fbaca567ca891503213ff8c344a1ea2e05Phil Burk // pid_t pid = -1, 983df348fbaca567ca891503213ff8c344a1ea2e05Phil Burk // const audio_attributes_t* pAttributes = nullptr 993df348fbaca567ca891503213ff8c344a1ea2e05Phil Burk ); 100e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 101e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk // Did we get a valid track? 102e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk status_t status = mAudioRecord->initCheck(); 103e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk if (status != OK) { 104e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk close(); 105e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk ALOGE("AudioStreamRecord::open(), initCheck() returned %d", status); 1065ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAudioConvert_androidToAAudioResult(status); 107e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 108e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 109e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk // Get the actual rate. 110e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk setSampleRate(mAudioRecord->getSampleRate()); 111e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk setSamplesPerFrame(mAudioRecord->channelCount()); 1125ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk setFormat(AAudioConvert_androidToAAudioDataFormat(mAudioRecord->format())); 113e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 114e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk // We may need to pass the data through a block size adapter to guarantee constant size. 115e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk if (mCallbackBufferSize != AAUDIO_UNSPECIFIED) { 116e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk int callbackSizeBytes = getBytesPerFrame() * mCallbackBufferSize; 117e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk mFixedBlockWriter.open(callbackSizeBytes); 118e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk mBlockAdapter = &mFixedBlockWriter; 119e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk } else { 120e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk mBlockAdapter = nullptr; 121e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk } 122e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 1235ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk setState(AAUDIO_STREAM_STATE_OPEN); 124e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 1255ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_OK; 126e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 127e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 1285ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkaaudio_result_t AudioStreamRecord::close() 129e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 130e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk // TODO add close() or release() to AudioRecord API then call it from here 1315ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk if (getState() != AAUDIO_STREAM_STATE_CLOSED) { 132e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk mAudioRecord.clear(); 1335ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk setState(AAUDIO_STREAM_STATE_CLOSED); 134e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 135e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk mFixedBlockWriter.close(); 1365ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_OK; 137e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 138e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 139e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burkvoid AudioStreamRecord::processCallback(int event, void *info) { 140e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 141e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk ALOGD("AudioStreamRecord::processCallback(), event %d", event); 142e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk switch (event) { 143e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk case AudioRecord::EVENT_MORE_DATA: 144e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk processCallbackCommon(AAUDIO_CALLBACK_OPERATION_PROCESS_DATA, info); 145e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk break; 146e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 147e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk // Stream got rerouted so we disconnect. 148e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk case AudioRecord::EVENT_NEW_IAUDIORECORD: 149e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk processCallbackCommon(AAUDIO_CALLBACK_OPERATION_DISCONNECTED, info); 150e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk break; 151e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 152e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk default: 153e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk break; 154e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk } 155e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk return; 156e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk} 157e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 1585ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkaaudio_result_t AudioStreamRecord::requestStart() 159e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 160d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk if (mAudioRecord.get() == nullptr) { 1615ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_ERROR_INVALID_STATE; 162e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 163e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk // Get current position so we can detect when the track is playing. 164e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk status_t err = mAudioRecord->getPosition(&mPositionWhenStarting); 165e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk if (err != OK) { 1665ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAudioConvert_androidToAAudioResult(err); 167e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 168e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 169e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk err = mAudioRecord->start(); 170e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk if (err != OK) { 1715ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAudioConvert_androidToAAudioResult(err); 172e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } else { 1735ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk setState(AAUDIO_STREAM_STATE_STARTING); 174e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 1755ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_OK; 176e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 177e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 1785ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkaaudio_result_t AudioStreamRecord::requestPause() 179e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 1805ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_ERROR_UNIMPLEMENTED; 181e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 182e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 1835ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkaaudio_result_t AudioStreamRecord::requestFlush() { 1845ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_ERROR_UNIMPLEMENTED; 185e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 186e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 1875ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkaaudio_result_t AudioStreamRecord::requestStop() { 188d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk if (mAudioRecord.get() == nullptr) { 1895ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_ERROR_INVALID_STATE; 190e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 1915ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk setState(AAUDIO_STREAM_STATE_STOPPING); 192e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk mAudioRecord->stop(); 1935ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_OK; 194e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 195e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 196e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burkaaudio_result_t AudioStreamRecord::updateStateWhileWaiting() 197e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 1985ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk aaudio_result_t result = AAUDIO_OK; 1995ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk aaudio_wrapping_frames_t position; 200e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk status_t err; 201e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk switch (getState()) { 202e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk // TODO add better state visibility to AudioRecord 2035ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk case AAUDIO_STREAM_STATE_STARTING: 204e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk err = mAudioRecord->getPosition(&position); 205e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk if (err != OK) { 2065ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk result = AAudioConvert_androidToAAudioResult(err); 207e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } else if (position != mPositionWhenStarting) { 2085ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk setState(AAUDIO_STREAM_STATE_STARTED); 209e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 210e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk break; 2115ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk case AAUDIO_STREAM_STATE_STOPPING: 212e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk if (mAudioRecord->stopped()) { 2135ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk setState(AAUDIO_STREAM_STATE_STOPPED); 214e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 215e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk break; 216e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk default: 217e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk break; 218e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 219e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk return result; 220e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 221e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 2225ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkaaudio_result_t AudioStreamRecord::read(void *buffer, 2233316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk int32_t numFrames, 2243316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk int64_t timeoutNanoseconds) 225e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 2263316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk int32_t bytesPerFrame = getBytesPerFrame(); 2273316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk int32_t numBytes; 2285ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk aaudio_result_t result = AAudioConvert_framesToBytes(numFrames, bytesPerFrame, &numBytes); 2295ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk if (result != AAUDIO_OK) { 230e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk return result; 231e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 232e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 233e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk // TODO add timeout to AudioRecord 234e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk bool blocking = (timeoutNanoseconds > 0); 235e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk ssize_t bytesRead = mAudioRecord->read(buffer, numBytes, blocking); 236e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk if (bytesRead == WOULD_BLOCK) { 237e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk return 0; 238e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } else if (bytesRead < 0) { 2395ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAudioConvert_androidToAAudioResult(bytesRead); 240e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 2413316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk int32_t framesRead = (int32_t)(bytesRead / bytesPerFrame); 2425ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return (aaudio_result_t) framesRead; 243e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 244e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 2453316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burkaaudio_result_t AudioStreamRecord::setBufferSize(int32_t requestedFrames) 246e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 2473316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk return getBufferSize(); 248e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 249e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 2503316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burkint32_t AudioStreamRecord::getBufferSize() const 251e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 252e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk return getBufferCapacity(); // TODO implement in AudioRecord? 253e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 254e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 2553316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burkint32_t AudioStreamRecord::getBufferCapacity() const 256e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 2573316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk return static_cast<int32_t>(mAudioRecord->frameCount()); 258e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 259e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 260e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burkint32_t AudioStreamRecord::getXRunCount() const 261e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 2625ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_ERROR_UNIMPLEMENTED; // TODO implement when AudioRecord supports it 263e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 264e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 2653316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burkint32_t AudioStreamRecord::getFramesPerBurst() const 266e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 267b588402d48c9634fa72e7e13ca6d6f2a0766cb98Phil Burk return static_cast<int32_t>(mAudioRecord->getNotificationPeriodInFrames()); 268e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 269e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 27035e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burkaaudio_result_t AudioStreamRecord::getTimestamp(clockid_t clockId, 27135e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk int64_t *framePosition, 27235e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk int64_t *timeNanoseconds) { 27335e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk ExtendedTimestamp extendedTimestamp; 27435e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk status_t status = mAudioRecord->getTimestamp(&extendedTimestamp); 27535e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk if (status != NO_ERROR) { 27635e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk return AAudioConvert_androidToAAudioResult(status); 27735e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk } 27835e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk // TODO Merge common code into AudioStreamLegacy after rebasing. 27935e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk int timebase; 28035e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk switch(clockId) { 28135e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk case CLOCK_BOOTTIME: 28235e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk timebase = ExtendedTimestamp::TIMEBASE_BOOTTIME; 28335e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk break; 28435e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk case CLOCK_MONOTONIC: 28535e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk timebase = ExtendedTimestamp::TIMEBASE_MONOTONIC; 28635e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk break; 28735e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk default: 28835e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk ALOGE("getTimestamp() - Unrecognized clock type %d", (int) clockId); 28935e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk return AAUDIO_ERROR_UNEXPECTED_VALUE; 29035e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk break; 29135e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk } 29235e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk status = extendedTimestamp.getBestTimestamp(framePosition, timeNanoseconds, timebase); 29335e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk return AAudioConvert_androidToAAudioResult(status); 29435e80f34a9649752fceafa53e2094cd8eda50a0aPhil Burk} 295