1e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk/* 2e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk * Copyright 2015 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 17965650e5c36f39cb5e6d780a22ff711fbf5a37f5Phil Burk#define LOG_TAG "AAudioStream" 18e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk//#define LOG_NDEBUG 0 19e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk#include <utils/Log.h> 20e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 21d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk#include <atomic> 22e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk#include <stdint.h> 235ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk#include <aaudio/AAudio.h> 24e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 25e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk#include "AudioStreamBuilder.h" 26e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk#include "AudioStream.h" 27e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk#include "AudioClock.h" 28e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 295ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkusing namespace aaudio; 30e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 31e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil BurkAudioStream::AudioStream() 32965650e5c36f39cb5e6d780a22ff711fbf5a37f5Phil Burk : mPlayerBase(new MyPlayerBase(this)) 33e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk{ 34d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk // mThread is a pthread_t of unknown size so we need memset. 35d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk memset(&mThread, 0, sizeof(mThread)); 36d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk setPeriodNanoseconds(0); 37e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 38e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 39965650e5c36f39cb5e6d780a22ff711fbf5a37f5Phil BurkAudioStream::~AudioStream() { 40965650e5c36f39cb5e6d780a22ff711fbf5a37f5Phil Burk ALOGD("destroying %p, state = %s", this, AAudio_convertStreamStateToText(getState())); 41965650e5c36f39cb5e6d780a22ff711fbf5a37f5Phil Burk // If the stream is deleted when OPEN or in use then audio resources will leak. 42965650e5c36f39cb5e6d780a22ff711fbf5a37f5Phil Burk // This would indicate an internal error. So we want to find this ASAP. 43965650e5c36f39cb5e6d780a22ff711fbf5a37f5Phil Burk LOG_ALWAYS_FATAL_IF(!(getState() == AAUDIO_STREAM_STATE_CLOSED 44965650e5c36f39cb5e6d780a22ff711fbf5a37f5Phil Burk || getState() == AAUDIO_STREAM_STATE_UNINITIALIZED 45965650e5c36f39cb5e6d780a22ff711fbf5a37f5Phil Burk || getState() == AAUDIO_STREAM_STATE_DISCONNECTED), 46134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk "~AudioStream() - still in use, state = %s", 47965650e5c36f39cb5e6d780a22ff711fbf5a37f5Phil Burk AAudio_convertStreamStateToText(getState())); 488a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk 498a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk mPlayerBase->clearParentReference(); // remove reference to this AudioStream 50965650e5c36f39cb5e6d780a22ff711fbf5a37f5Phil Burk} 51965650e5c36f39cb5e6d780a22ff711fbf5a37f5Phil Burk 52ec89b2e2f8c84a7d3936db1a888034f4a4b0df16Phil Burkstatic const char *AudioStream_convertSharingModeToShortText(aaudio_sharing_mode_t sharingMode) { 53ec89b2e2f8c84a7d3936db1a888034f4a4b0df16Phil Burk const char *result; 54ec89b2e2f8c84a7d3936db1a888034f4a4b0df16Phil Burk switch (sharingMode) { 55ec89b2e2f8c84a7d3936db1a888034f4a4b0df16Phil Burk case AAUDIO_SHARING_MODE_EXCLUSIVE: 56ec89b2e2f8c84a7d3936db1a888034f4a4b0df16Phil Burk result = "EX"; 57ec89b2e2f8c84a7d3936db1a888034f4a4b0df16Phil Burk break; 58ec89b2e2f8c84a7d3936db1a888034f4a4b0df16Phil Burk case AAUDIO_SHARING_MODE_SHARED: 59ec89b2e2f8c84a7d3936db1a888034f4a4b0df16Phil Burk result = "SH"; 60ec89b2e2f8c84a7d3936db1a888034f4a4b0df16Phil Burk break; 61ec89b2e2f8c84a7d3936db1a888034f4a4b0df16Phil Burk default: 62ec89b2e2f8c84a7d3936db1a888034f4a4b0df16Phil Burk result = "?!"; 63ec89b2e2f8c84a7d3936db1a888034f4a4b0df16Phil Burk break; 64ec89b2e2f8c84a7d3936db1a888034f4a4b0df16Phil Burk } 65ec89b2e2f8c84a7d3936db1a888034f4a4b0df16Phil Burk return result; 66ec89b2e2f8c84a7d3936db1a888034f4a4b0df16Phil Burk} 67ec89b2e2f8c84a7d3936db1a888034f4a4b0df16Phil Burk 685ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkaaudio_result_t AudioStream::open(const AudioStreamBuilder& builder) 69e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 703401bcdd98c5a43a14701a0e7299a2318c6863c9Phil Burk // Call here as well because the AAudioService will call this without calling build(). 713401bcdd98c5a43a14701a0e7299a2318c6863c9Phil Burk aaudio_result_t result = builder.validate(); 723401bcdd98c5a43a14701a0e7299a2318c6863c9Phil Burk if (result != AAUDIO_OK) { 733401bcdd98c5a43a14701a0e7299a2318c6863c9Phil Burk return result; 743401bcdd98c5a43a14701a0e7299a2318c6863c9Phil Burk } 753401bcdd98c5a43a14701a0e7299a2318c6863c9Phil Burk 76e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk // Copy parameters from the Builder because the Builder may be deleted after this call. 77d4ccc624201d5c74ff6e14db1b68743b41fe795cPhil Burk // TODO AudioStream should be a subclass of AudioStreamParameters 78e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk mSamplesPerFrame = builder.getSamplesPerFrame(); 79e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk mSampleRate = builder.getSampleRate(); 80e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk mDeviceId = builder.getDeviceId(); 81e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk mFormat = builder.getFormat(); 82c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk mSharingMode = builder.getSharingMode(); 8371f35bb687476694882a617ba4a810a0bb56fe23Phil Burk mSharingModeMatchRequired = builder.isSharingModeMatchRequired(); 84e2fbb59e729f6c3cade3b531f6f6411417ccbf40Phil Burk mPerformanceMode = builder.getPerformanceMode(); 85e2fbb59e729f6c3cade3b531f6f6411417ccbf40Phil Burk 86d4ccc624201d5c74ff6e14db1b68743b41fe795cPhil Burk mUsage = builder.getUsage(); 87d4ccc624201d5c74ff6e14db1b68743b41fe795cPhil Burk if (mUsage == AAUDIO_UNSPECIFIED) { 88d4ccc624201d5c74ff6e14db1b68743b41fe795cPhil Burk mUsage = AAUDIO_USAGE_MEDIA; 89d4ccc624201d5c74ff6e14db1b68743b41fe795cPhil Burk } 90d4ccc624201d5c74ff6e14db1b68743b41fe795cPhil Burk mContentType = builder.getContentType(); 91d4ccc624201d5c74ff6e14db1b68743b41fe795cPhil Burk if (mContentType == AAUDIO_UNSPECIFIED) { 92d4ccc624201d5c74ff6e14db1b68743b41fe795cPhil Burk mContentType = AAUDIO_CONTENT_TYPE_MUSIC; 93d4ccc624201d5c74ff6e14db1b68743b41fe795cPhil Burk } 94d4ccc624201d5c74ff6e14db1b68743b41fe795cPhil Burk mInputPreset = builder.getInputPreset(); 95d4ccc624201d5c74ff6e14db1b68743b41fe795cPhil Burk if (mInputPreset == AAUDIO_UNSPECIFIED) { 96eaef9b9c7b3c6c4d4435ce5e32e9fe952a2f69fePhil Burk mInputPreset = AAUDIO_INPUT_PRESET_VOICE_RECOGNITION; 97d4ccc624201d5c74ff6e14db1b68743b41fe795cPhil Burk } 98d4ccc624201d5c74ff6e14db1b68743b41fe795cPhil Burk 99e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk // callbacks 100e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk mFramesPerDataCallback = builder.getFramesPerDataCallback(); 101e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk mDataCallbackProc = builder.getDataCallbackProc(); 102e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk mErrorCallbackProc = builder.getErrorCallbackProc(); 103e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk mDataCallbackUserData = builder.getDataCallbackUserData(); 104098b883a7dc89b65b72c6d3f1d38c6afd477a0adPhil Burk mErrorCallbackUserData = builder.getErrorCallbackUserData(); 105e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 106cf5f6d2825d9a8430a291042ca9c6f68e5b666d0Phil Burk // This is very helpful for debugging in the future. Please leave it in. 10719e990e480245af25ec03ff3a3f53b820b0732cdPhil Burk ALOGI("open() rate = %d, channels = %d, format = %d, sharing = %s, dir = %s", 108ec89b2e2f8c84a7d3936db1a888034f4a4b0df16Phil Burk mSampleRate, mSamplesPerFrame, mFormat, 109ec89b2e2f8c84a7d3936db1a888034f4a4b0df16Phil Burk AudioStream_convertSharingModeToShortText(mSharingMode), 110cf5f6d2825d9a8430a291042ca9c6f68e5b666d0Phil Burk (getDirection() == AAUDIO_DIRECTION_OUTPUT) ? "OUTPUT" : "INPUT"); 11119e990e480245af25ec03ff3a3f53b820b0732cdPhil Burk ALOGI("open() device = %d, sessionId = %d, perfMode = %d, callback: %s with frames = %d", 1124e1af9fc9c1108d4514e92774f750bcd434dbbccPhil Burk mDeviceId, 1134e1af9fc9c1108d4514e92774f750bcd434dbbccPhil Burk mSessionId, 1144e1af9fc9c1108d4514e92774f750bcd434dbbccPhil Burk mPerformanceMode, 115134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk (isDataCallbackSet() ? "ON" : "OFF"), 116fd34a9310659aa53e9e10d6826651577a75f6447Phil Burk mFramesPerDataCallback); 11719e990e480245af25ec03ff3a3f53b820b0732cdPhil Burk ALOGI("open() usage = %d, contentType = %d, inputPreset = %d", 118a62fb9565d73d9ec9b56da65929afc0f686c696ePhil Burk mUsage, mContentType, mInputPreset); 119e2fbb59e729f6c3cade3b531f6f6411417ccbf40Phil Burk 1205ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_OK; 121e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 122e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 123134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burkaaudio_result_t AudioStream::safeStart() { 124134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk std::lock_guard<std::mutex> lock(mStreamLock); 125134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk if (collidesWithCallback()) { 126134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk ALOGE("%s cannot be called from a callback!", __func__); 127134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk return AAUDIO_ERROR_INVALID_STATE; 128134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk } 129134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk return requestStart(); 130134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk} 131134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk 132134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burkaaudio_result_t AudioStream::safePause() { 1335cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk if (!isPauseSupported()) { 1345cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk return AAUDIO_ERROR_UNIMPLEMENTED; 1355cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk } 1365cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk 137134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk std::lock_guard<std::mutex> lock(mStreamLock); 138134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk if (collidesWithCallback()) { 139134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk ALOGE("%s cannot be called from a callback!", __func__); 140134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk return AAUDIO_ERROR_INVALID_STATE; 141134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk } 1425cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk 1435cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk switch (getState()) { 1445cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk // Proceed with pausing. 1455cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk case AAUDIO_STREAM_STATE_STARTING: 1465cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk case AAUDIO_STREAM_STATE_STARTED: 1475cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk case AAUDIO_STREAM_STATE_DISCONNECTED: 1485cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk break; 1495cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk 1505cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk // Transition from one inactive state to another. 1515cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk case AAUDIO_STREAM_STATE_OPEN: 1525cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk case AAUDIO_STREAM_STATE_STOPPED: 1535cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk case AAUDIO_STREAM_STATE_FLUSHED: 1545cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk setState(AAUDIO_STREAM_STATE_PAUSED); 1555cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk return AAUDIO_OK; 1565cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk 1575cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk // Redundant? 1585cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk case AAUDIO_STREAM_STATE_PAUSING: 1595cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk case AAUDIO_STREAM_STATE_PAUSED: 1605cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk return AAUDIO_OK; 1615cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk 1625cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk // Don't interfere with transitional states or when closed. 1635cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk case AAUDIO_STREAM_STATE_STOPPING: 1645cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk case AAUDIO_STREAM_STATE_FLUSHING: 1655cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk case AAUDIO_STREAM_STATE_CLOSING: 1665cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk case AAUDIO_STREAM_STATE_CLOSED: 1675cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk default: 1685cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk ALOGW("safePause() stream not running, state = %s", 1695cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk AAudio_convertStreamStateToText(getState())); 1705cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk return AAUDIO_ERROR_INVALID_STATE; 1715cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk } 1725cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk 173134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk return requestPause(); 174134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk} 175134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk 176134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burkaaudio_result_t AudioStream::safeFlush() { 1775cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk if (!isFlushSupported()) { 1785cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk ALOGE("flush not supported for this stream"); 1795cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk return AAUDIO_ERROR_UNIMPLEMENTED; 1805cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk } 1815cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk 182134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk std::lock_guard<std::mutex> lock(mStreamLock); 183134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk if (collidesWithCallback()) { 1845cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk ALOGE("stream cannot be flushed from a callback!"); 185134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk return AAUDIO_ERROR_INVALID_STATE; 186134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk } 1875cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk 1885cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk aaudio_result_t result = AAudio_isFlushAllowed(getState()); 1895cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk if (result != AAUDIO_OK) { 1905cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk return result; 1915cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk } 1925cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk 193134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk return requestFlush(); 194134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk} 195134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk 196134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burkaaudio_result_t AudioStream::safeStop() { 197134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk std::lock_guard<std::mutex> lock(mStreamLock); 198134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk if (collidesWithCallback()) { 1995cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk ALOGE("stream cannot be stopped from a callback!"); 200134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk return AAUDIO_ERROR_INVALID_STATE; 201134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk } 2025cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk 2035cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk switch (getState()) { 2045cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk // Proceed with stopping. 2055cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk case AAUDIO_STREAM_STATE_STARTING: 2065cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk case AAUDIO_STREAM_STATE_STARTED: 2075cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk case AAUDIO_STREAM_STATE_DISCONNECTED: 2085cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk break; 2095cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk 2105cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk // Transition from one inactive state to another. 2115cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk case AAUDIO_STREAM_STATE_OPEN: 2125cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk case AAUDIO_STREAM_STATE_PAUSED: 2135cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk case AAUDIO_STREAM_STATE_FLUSHED: 2145cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk setState(AAUDIO_STREAM_STATE_STOPPED); 2155cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk return AAUDIO_OK; 2165cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk 2175cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk // Redundant? 2185cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk case AAUDIO_STREAM_STATE_STOPPING: 2195cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk case AAUDIO_STREAM_STATE_STOPPED: 2205cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk return AAUDIO_OK; 2215cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk 2225cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk // Don't interfere with transitional states or when closed. 2235cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk case AAUDIO_STREAM_STATE_PAUSING: 2245cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk case AAUDIO_STREAM_STATE_FLUSHING: 2255cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk case AAUDIO_STREAM_STATE_CLOSING: 2265cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk case AAUDIO_STREAM_STATE_CLOSED: 2275cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk default: 2285cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk ALOGW("requestStop() stream not running, state = %s", 2295cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk AAudio_convertStreamStateToText(getState())); 2305cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk return AAUDIO_ERROR_INVALID_STATE; 2315cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk } 2325cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk 233134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk return requestStop(); 234134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk} 235134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk 236134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burkaaudio_result_t AudioStream::safeClose() { 237134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk std::lock_guard<std::mutex> lock(mStreamLock); 238134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk if (collidesWithCallback()) { 239134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk ALOGE("%s cannot be called from a callback!", __func__); 240134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk return AAUDIO_ERROR_INVALID_STATE; 241134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk } 242134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk return close(); 243134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk} 244e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 24519e990e480245af25ec03ff3a3f53b820b0732cdPhil Burkvoid AudioStream::setState(aaudio_stream_state_t state) { 24619e990e480245af25ec03ff3a3f53b820b0732cdPhil Burk ALOGV("%s(%p) from %d to %d", __func__, this, mState, state); 24719e990e480245af25ec03ff3a3f53b820b0732cdPhil Burk // CLOSED is a final state 24819e990e480245af25ec03ff3a3f53b820b0732cdPhil Burk if (mState == AAUDIO_STREAM_STATE_CLOSED) { 24919e990e480245af25ec03ff3a3f53b820b0732cdPhil Burk ALOGE("%s(%p) tried to set to %d but already CLOSED", __func__, this, state); 25019e990e480245af25ec03ff3a3f53b820b0732cdPhil Burk 25119e990e480245af25ec03ff3a3f53b820b0732cdPhil Burk // Once DISCONNECTED, we can only move to CLOSED state. 25219e990e480245af25ec03ff3a3f53b820b0732cdPhil Burk } else if (mState == AAUDIO_STREAM_STATE_DISCONNECTED 25319e990e480245af25ec03ff3a3f53b820b0732cdPhil Burk && state != AAUDIO_STREAM_STATE_CLOSED) { 25419e990e480245af25ec03ff3a3f53b820b0732cdPhil Burk ALOGE("%s(%p) tried to set to %d but already DISCONNECTED", __func__, this, state); 25519e990e480245af25ec03ff3a3f53b820b0732cdPhil Burk 25619e990e480245af25ec03ff3a3f53b820b0732cdPhil Burk } else { 25719e990e480245af25ec03ff3a3f53b820b0732cdPhil Burk mState = state; 25819e990e480245af25ec03ff3a3f53b820b0732cdPhil Burk } 25919e990e480245af25ec03ff3a3f53b820b0732cdPhil Burk} 26019e990e480245af25ec03ff3a3f53b820b0732cdPhil Burk 2615ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkaaudio_result_t AudioStream::waitForStateChange(aaudio_stream_state_t currentState, 2625ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk aaudio_stream_state_t *nextState, 2633316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk int64_t timeoutNanoseconds) 264e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 2650befec600314a79c0d142c3edd99f7d1c75e1afePhil Burk aaudio_result_t result = updateStateMachine(); 266e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk if (result != AAUDIO_OK) { 267e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk return result; 268e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk } 269e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk 270e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk int64_t durationNanos = 20 * AAUDIO_NANOS_PER_MILLISECOND; // arbitrary 2715ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk aaudio_stream_state_t state = getState(); 272e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk while (state == currentState && timeoutNanoseconds > 0) { 273e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk if (durationNanos > timeoutNanoseconds) { 274e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk durationNanos = timeoutNanoseconds; 275e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 276e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk AudioClock::sleepForNanos(durationNanos); 277e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk timeoutNanoseconds -= durationNanos; 278e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 2790befec600314a79c0d142c3edd99f7d1c75e1afePhil Burk aaudio_result_t result = updateStateMachine(); 2805ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk if (result != AAUDIO_OK) { 281e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk return result; 282e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 283e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 284e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk state = getState(); 285e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 286d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk if (nextState != nullptr) { 287e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk *nextState = state; 288e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 2895ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return (state == currentState) ? AAUDIO_ERROR_TIMEOUT : AAUDIO_OK; 290e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 291e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 29271f35bb687476694882a617ba4a810a0bb56fe23Phil Burk// This registers the callback thread with the server before 293d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk// passing control to the app. This gives the server an opportunity to boost 294d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk// the thread's performance characteristics. 295d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burkvoid* AudioStream::wrapUserThread() { 296d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk void* procResult = nullptr; 297d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk mThreadRegistrationResult = registerThread(); 2985ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk if (mThreadRegistrationResult == AAUDIO_OK) { 29971f35bb687476694882a617ba4a810a0bb56fe23Phil Burk // Run callback loop. This may take a very long time. 300d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk procResult = mThreadProc(mThreadArg); 301d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk mThreadRegistrationResult = unregisterThread(); 302d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk } 303d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk return procResult; 304d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk} 305d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk 306d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk// This is the entry point for the new thread created by createThread(). 307d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk// It converts the 'C' function call to a C++ method call. 308d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burkstatic void* AudioStream_internalThreadProc(void* threadArg) { 309d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk AudioStream *audioStream = (AudioStream *) threadArg; 310d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk return audioStream->wrapUserThread(); 311d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk} 312d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk 3135204d315c6c6f53188f8d1414dd1b55b6c90142bPhil Burk// This is not exposed in the API. 3145204d315c6c6f53188f8d1414dd1b55b6c90142bPhil Burk// But it is still used internally to implement callbacks for MMAP mode. 3153316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burkaaudio_result_t AudioStream::createThread(int64_t periodNanoseconds, 316e2155ef0ec6742db7a3128c4ef4fb96e02828d1bPhil Burk aaudio_audio_thread_proc_t threadProc, 317d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk void* threadArg) 318e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 319e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk if (mHasThread) { 320fbf031e8f197c916ae9c399f42926494ebdeb497Phil Burk ALOGE("createThread() - mHasThread already true"); 3215ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_ERROR_INVALID_STATE; 322e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 323d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk if (threadProc == nullptr) { 3245ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_ERROR_NULL; 325e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 326d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk // Pass input parameters to the background thread. 327d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk mThreadProc = threadProc; 328d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk mThreadArg = threadArg; 329d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk setPeriodNanoseconds(periodNanoseconds); 330d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk int err = pthread_create(&mThread, nullptr, AudioStream_internalThreadProc, this); 331e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk if (err != 0) { 33219e990e480245af25ec03ff3a3f53b820b0732cdPhil Burk android::status_t status = -errno; 33319e990e480245af25ec03ff3a3f53b820b0732cdPhil Burk ALOGE("createThread() - pthread_create() failed, %d", status); 33419e990e480245af25ec03ff3a3f53b820b0732cdPhil Burk return AAudioConvert_androidToAAudioResult(status); 335e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } else { 3365cc83c3b8acc43b760be23a4e3b96fbbb06d8e93Phil Burk // TODO Use AAudioThread or maybe AndroidThread 337559788963268a0bc1e90e29c423ac78938c96b4aPhil Burk // Name the thread with an increasing index, "AAudio_#", for debugging. 338559788963268a0bc1e90e29c423ac78938c96b4aPhil Burk static std::atomic<uint32_t> nextThreadIndex{1}; 339559788963268a0bc1e90e29c423ac78938c96b4aPhil Burk char name[16]; // max length for a pthread_name 340559788963268a0bc1e90e29c423ac78938c96b4aPhil Burk uint32_t index = nextThreadIndex++; 341559788963268a0bc1e90e29c423ac78938c96b4aPhil Burk // Wrap the index so that we do not hit the 16 char limit 342559788963268a0bc1e90e29c423ac78938c96b4aPhil Burk // and to avoid hard-to-read large numbers. 343559788963268a0bc1e90e29c423ac78938c96b4aPhil Burk index = index % 100000; // arbitrary 344559788963268a0bc1e90e29c423ac78938c96b4aPhil Burk snprintf(name, sizeof(name), "AAudio_%u", index); 345559788963268a0bc1e90e29c423ac78938c96b4aPhil Burk err = pthread_setname_np(mThread, name); 346559788963268a0bc1e90e29c423ac78938c96b4aPhil Burk ALOGW_IF((err != 0), "Could not set name of AAudio thread. err = %d", err); 347559788963268a0bc1e90e29c423ac78938c96b4aPhil Burk 348e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk mHasThread = true; 3495ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_OK; 350e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 351e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 352e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 3533316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burkaaudio_result_t AudioStream::joinThread(void** returnArg, int64_t timeoutNanoseconds) 354e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk{ 355e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk if (!mHasThread) { 356fbf031e8f197c916ae9c399f42926494ebdeb497Phil Burk ALOGE("joinThread() - but has no thread"); 3575ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk return AAUDIO_ERROR_INVALID_STATE; 358e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk } 359e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk#if 0 360e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk // TODO implement equivalent of pthread_timedjoin_np() 361e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk struct timespec abstime; 362e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk int err = pthread_timedjoin_np(mThread, returnArg, &abstime); 363e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk#else 364e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk int err = pthread_join(mThread, returnArg); 365e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk#endif 366e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk mHasThread = false; 3675204d315c6c6f53188f8d1414dd1b55b6c90142bPhil Burk return err ? AAudioConvert_androidToAAudioResult(-errno) : mThreadRegistrationResult; 368e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk} 369e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk 370134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burkaaudio_data_callback_result_t AudioStream::maybeCallDataCallback(void *audioData, 371134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk int32_t numFrames) { 372134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk aaudio_data_callback_result_t result = AAUDIO_CALLBACK_RESULT_STOP; 373134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk AAudioStream_dataCallback dataCallback = getDataCallbackProc(); 374134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk if (dataCallback != nullptr) { 375134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk // Store thread ID of caller to detect stop() and close() calls from callback. 376134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk pid_t expected = CALLBACK_THREAD_NONE; 377134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk if (mDataCallbackThread.compare_exchange_strong(expected, gettid())) { 378134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk result = (*dataCallback)( 379134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk (AAudioStream *) this, 380134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk getDataCallbackUserData(), 381134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk audioData, 382134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk numFrames); 383134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk mDataCallbackThread.store(CALLBACK_THREAD_NONE); 384134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk } else { 385134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk ALOGW("%s() data callback already running!", __func__); 386134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk } 387134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk } 388134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk return result; 389134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk} 390134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk 391134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burkvoid AudioStream::maybeCallErrorCallback(aaudio_result_t result) { 392134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk AAudioStream_errorCallback errorCallback = getErrorCallbackProc(); 393134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk if (errorCallback != nullptr) { 394134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk // Store thread ID of caller to detect stop() and close() calls from callback. 395134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk pid_t expected = CALLBACK_THREAD_NONE; 396134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk if (mErrorCallbackThread.compare_exchange_strong(expected, gettid())) { 397134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk (*errorCallback)( 398134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk (AAudioStream *) this, 399134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk getErrorCallbackUserData(), 400134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk result); 401134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk mErrorCallbackThread.store(CALLBACK_THREAD_NONE); 402134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk } else { 403134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk ALOGW("%s() error callback already running!", __func__); 404134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk } 405134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk } 406134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk} 407134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk 408134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk// Is this running on the same thread as a callback? 409134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk// Note: This cannot be implemented using a thread_local because that would 410134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk// require using a thread_local variable that is shared between streams. 411134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk// So a thread_local variable would prevent stopping or closing stream A from 412134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk// a callback on stream B, which is currently legal and not so terrible. 413134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burkbool AudioStream::collidesWithCallback() const { 414134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk pid_t thisThread = gettid(); 415134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk // Compare the current thread ID with the thread ID of the callback 416134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk // threads to see it they match. If so then this code is being 417134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk // called from one of the stream callback functions. 418134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk return ((mErrorCallbackThread.load() == thisThread) 419134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk || (mDataCallbackThread.load() == thisThread)); 420134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk} 421134f197bf7e2785ed9de336dc8e22e870c2ba6bdPhil Burk 4228a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk#if AAUDIO_USE_VOLUME_SHAPER 4238a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burkandroid::media::VolumeShaper::Status AudioStream::applyVolumeShaper( 4248a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk const android::media::VolumeShaper::Configuration& configuration __unused, 4258a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk const android::media::VolumeShaper::Operation& operation __unused) { 4268a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk ALOGW("applyVolumeShaper() is not supported"); 4278a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk return android::media::VolumeShaper::Status::ok(); 4288a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk} 4298a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk#endif 4308a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk 43155e5eabf96af5a2964bfab1e64d81ad9be9ac975Phil Burkvoid AudioStream::setDuckAndMuteVolume(float duckAndMuteVolume) { 43255e5eabf96af5a2964bfab1e64d81ad9be9ac975Phil Burk ALOGD("%s() to %f", __func__, duckAndMuteVolume); 43355e5eabf96af5a2964bfab1e64d81ad9be9ac975Phil Burk mDuckAndMuteVolume = duckAndMuteVolume; 43455e5eabf96af5a2964bfab1e64d81ad9be9ac975Phil Burk doSetVolume(); // apply this change 43555e5eabf96af5a2964bfab1e64d81ad9be9ac975Phil Burk} 43655e5eabf96af5a2964bfab1e64d81ad9be9ac975Phil Burk 4378a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil BurkAudioStream::MyPlayerBase::MyPlayerBase(AudioStream *parent) : mParent(parent) { 4388a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk} 4398a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk 4408a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil BurkAudioStream::MyPlayerBase::~MyPlayerBase() { 4418a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk ALOGV("MyPlayerBase::~MyPlayerBase(%p) deleted", this); 4428a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk} 4438a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk 4448a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burkvoid AudioStream::MyPlayerBase::registerWithAudioManager() { 4458a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk if (!mRegistered) { 4468a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk init(android::PLAYER_TYPE_AAUDIO, AUDIO_USAGE_MEDIA); 4478a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk mRegistered = true; 4488a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk } 4498a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk} 4508a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk 4518a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burkvoid AudioStream::MyPlayerBase::unregisterWithAudioManager() { 4528a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk if (mRegistered) { 4538a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk baseDestroy(); 4548a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk mRegistered = false; 4558a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk } 4568a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk} 4578a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk 4588a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burkvoid AudioStream::MyPlayerBase::destroy() { 4598a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk unregisterWithAudioManager(); 4608a8a9e5d91c8cc110b9916982f4c5242efca33e3Phil Burk} 461