AudioFlinger.cpp revision d65d73c4ae74d084751b417615a78cbe7a51372a
199e53b86eebb605b70dd7591b89bf61a9414ed0eGlenn Kasten/*
265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian**
365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** Copyright 2007, The Android Open Source Project
465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian**
565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** Licensed under the Apache License, Version 2.0 (the "License");
665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** you may not use this file except in compliance with the License.
765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** You may obtain a copy of the License at
865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian**
965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian**     http://www.apache.org/licenses/LICENSE-2.0
1065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian**
1165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** Unless required by applicable law or agreed to in writing, software
1265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** distributed under the License is distributed on an "AS IS" BASIS,
1365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** See the License for the specific language governing permissions and
1565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** limitations under the License.
1665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian*/
1765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define LOG_TAG "AudioFlinger"
2065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian//#define LOG_NDEBUG 0
2165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <math.h>
2365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <signal.h>
2465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <sys/time.h>
2565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <sys/resource.h>
2665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
279ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang#include <binder/IPCThreadState.h>
2865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IServiceManager.h>
2965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/Log.h>
30d8e6fd35ec2b59ee7d873daf1f1d9d348221c7bcGlenn Kasten#include <utils/Trace.h>
3165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/Parcel.h>
3265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IPCThreadState.h>
3365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/String16.h>
3465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/threads.h>
3538ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent#include <utils/Atomic.h>
3665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
37fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin#include <cutils/bitops.h>
3865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <cutils/properties.h>
39f6b1678f8f508b447155a81b44e214475ab634a8Glenn Kasten#include <cutils/compiler.h>
4065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
41d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten#undef ADD_BATTERY_DATA
42d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten
43d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten#ifdef ADD_BATTERY_DATA
449ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang#include <media/IMediaPlayerService.h>
4525b248eb52a0a16adaef6b79c9d92cb88b9a2bc2Glenn Kasten#include <media/IMediaDeathNotifier.h>
46d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten#endif
4765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <private/media/AudioTrackShared.h>
4965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <private/media/AudioEffectShared.h>
50fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
5164760240f931714858a59c1579f07264d7182ba2Dima Zavin#include <system/audio.h>
527394a4f358fa9908a9f0a7c954b65c399f4268e6Dima Zavin#include <hardware/audio.h>
5365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "AudioMixer.h"
5565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "AudioFlinger.h"
5644deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten#include "ServiceUtilities.h"
5765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/EffectsFactoryApi.h>
596d8b694d999e9be7d5dcc336535832a80fb6f61fEric Laurent#include <audio_effects/effect_visualizer.h>
6059bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent#include <audio_effects/effect_ns.h>
6159bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent#include <audio_effects/effect_aec.h>
6265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
633b21c50ef95fe4e7ac3426ca14b365749e66ff08Glenn Kasten#include <audio_utils/primitives.h>
643b21c50ef95fe4e7ac3426ca14b365749e66ff08Glenn Kasten
65feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent#include <powermanager/PowerManager.h>
66190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
674d8d0c30abfa4b8d75866d42094cc797e05068faGlenn Kasten// #define DEBUG_CPU_USAGE 10  // log statistics every n wall clock seconds
68190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten#ifdef DEBUG_CPU_USAGE
69190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten#include <cpustats/CentralTendencyStatistics.h>
70190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten#include <cpustats/ThreadCpuUsage.h>
71190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten#endif
724d8d0c30abfa4b8d75866d42094cc797e05068faGlenn Kasten
734ff14bae91075eb274eb1c2975982358946e7e63John Grossman#include <common_time/cc_helper.h>
744ff14bae91075eb274eb1c2975982358946e7e63John Grossman#include <common_time/local_clock.h>
754ff14bae91075eb274eb1c2975982358946e7e63John Grossman
7658912562617941964939a4182cda71eaeb153d4bGlenn Kasten#include "FastMixer.h"
7758912562617941964939a4182cda71eaeb153d4bGlenn Kasten
7858912562617941964939a4182cda71eaeb153d4bGlenn Kasten// NBAIO implementations
792dd4bdd715f586d4d30cf90cc6fc2bbfbce60fe0Glenn Kasten#include <media/nbaio/AudioStreamOutSink.h>
802dd4bdd715f586d4d30cf90cc6fc2bbfbce60fe0Glenn Kasten#include <media/nbaio/MonoPipe.h>
812dd4bdd715f586d4d30cf90cc6fc2bbfbce60fe0Glenn Kasten#include <media/nbaio/MonoPipeReader.h>
822dd4bdd715f586d4d30cf90cc6fc2bbfbce60fe0Glenn Kasten#include <media/nbaio/Pipe.h>
832dd4bdd715f586d4d30cf90cc6fc2bbfbce60fe0Glenn Kasten#include <media/nbaio/PipeReader.h>
842dd4bdd715f586d4d30cf90cc6fc2bbfbce60fe0Glenn Kasten#include <media/nbaio/SourceAudioBufferProvider.h>
8558912562617941964939a4182cda71eaeb153d4bGlenn Kasten
861dc28b794587be22c90a97070d928f94586db638Glenn Kasten#include "SchedulingPolicyService.h"
8758912562617941964939a4182cda71eaeb153d4bGlenn Kasten
8865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
8965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
901c345196edc61694f29307a1826a64a0d26028dcJohn Grossman// Note: the following macro is used for extremely verbose logging message.  In
911c345196edc61694f29307a1826a64a0d26028dcJohn Grossman// order to run with ALOG_ASSERT turned on, we need to have LOG_NDEBUG set to
921c345196edc61694f29307a1826a64a0d26028dcJohn Grossman// 0; but one side effect of this is to turn all LOGV's as well.  Some messages
931c345196edc61694f29307a1826a64a0d26028dcJohn Grossman// are so verbose that we want to suppress them even when we have ALOG_ASSERT
941c345196edc61694f29307a1826a64a0d26028dcJohn Grossman// turned on.  Do not uncomment the #def below unless you really know what you
951c345196edc61694f29307a1826a64a0d26028dcJohn Grossman// are doing and want to see all of the extremely verbose messages.
961c345196edc61694f29307a1826a64a0d26028dcJohn Grossman//#define VERY_VERY_VERBOSE_LOGGING
971c345196edc61694f29307a1826a64a0d26028dcJohn Grossman#ifdef VERY_VERY_VERBOSE_LOGGING
981c345196edc61694f29307a1826a64a0d26028dcJohn Grossman#define ALOGVV ALOGV
991c345196edc61694f29307a1826a64a0d26028dcJohn Grossman#else
1001c345196edc61694f29307a1826a64a0d26028dcJohn Grossman#define ALOGVV(a...) do { } while(0)
1011c345196edc61694f29307a1826a64a0d26028dcJohn Grossman#endif
102de070137f11d346fba77605bd76a44c040a618fcEric Laurent
10365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiannamespace android {
10465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
105ec1d6b5e17281a066d618f7fcd2b63b3ce11f421Glenn Kastenstatic const char kDeadlockedString[] = "AudioFlinger may be deadlocked\n";
106ec1d6b5e17281a066d618f7fcd2b63b3ce11f421Glenn Kastenstatic const char kHardwareLockedString[] = "Hardware lock is taken\n";
10765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
10865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const float MAX_GAIN = 4096.0f;
109b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kastenstatic const uint32_t MAX_GAIN_INT = 0x1000;
11065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
11165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// retry counts for buffer fill timeout
11265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// 50 * ~20msecs = 1 second
11365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int8_t kMaxTrackRetries = 50;
11465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int8_t kMaxTrackStartupRetries = 50;
11565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// allow less retry attempts on direct output thread.
11665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// direct outputs can be a scarce resource in audio hardware and should
11765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// be released as quickly as possible.
11865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int8_t kMaxTrackRetriesDirect = 2;
11965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
12065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockRetries = 50;
1217dede876998ff56351d495ec3a798c1b131193e8Glenn Kastenstatic const int kDumpLockSleepUs = 20000;
12265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1237dede876998ff56351d495ec3a798c1b131193e8Glenn Kasten// don't warn about blocked writes or record buffer overflows more often than this
1247dede876998ff56351d495ec3a798c1b131193e8Glenn Kastenstatic const nsecs_t kWarningThrottleNs = seconds(5);
12565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1267c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent// RecordThread loop sleep time upon application overrun or audio HAL read error
1277c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurentstatic const int kRecordThreadSleepUs = 5000;
12865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1297dede876998ff56351d495ec3a798c1b131193e8Glenn Kasten// maximum time to wait for setParameters to complete
1307dede876998ff56351d495ec3a798c1b131193e8Glenn Kastenstatic const nsecs_t kSetParametersTimeoutNs = seconds(2);
13160cd0a0d488e604d27fc7dbb02b00348693dfde2Eric Laurent
1327cafbb32999049873d4746ba83bd20c88abe6ce6Eric Laurent// minimum sleep time for the mixer thread loop when tracks are active but in underrun
1337cafbb32999049873d4746ba83bd20c88abe6ce6Eric Laurentstatic const uint32_t kMinThreadSleepTimeUs = 5000;
1347cafbb32999049873d4746ba83bd20c88abe6ce6Eric Laurent// maximum divider applied to the active sleep time in the mixer thread loop
1357cafbb32999049873d4746ba83bd20c88abe6ce6Eric Laurentstatic const uint32_t kMaxThreadSleepTimeShift = 2;
1367cafbb32999049873d4746ba83bd20c88abe6ce6Eric Laurent
13758912562617941964939a4182cda71eaeb153d4bGlenn Kasten// minimum normal mix buffer size, expressed in milliseconds rather than frames
13858912562617941964939a4182cda71eaeb153d4bGlenn Kastenstatic const uint32_t kMinNormalMixBufferSizeMs = 20;
1394adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten// maximum normal mix buffer size
1404adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kastenstatic const uint32_t kMaxNormalMixBufferSizeMs = 24;
14158912562617941964939a4182cda71eaeb153d4bGlenn Kasten
1424ff14bae91075eb274eb1c2975982358946e7e63John Grossmannsecs_t AudioFlinger::mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;
1437cafbb32999049873d4746ba83bd20c88abe6ce6Eric Laurent
144300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten// Whether to use fast mixer
145300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kastenstatic const enum {
146300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    FastMixer_Never,    // never initialize or use: for debugging only
147300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    FastMixer_Always,   // always initialize and use, even if not needed: for debugging only
148300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten                        // normal mixer multiplier is 1
149300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    FastMixer_Static,   // initialize if needed, then use all the time if initialized,
1504adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten                        // multiplier is calculated based on min & max normal mixer buffer size
151300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    FastMixer_Dynamic,  // initialize if needed, then use dynamically depending on track load,
1524adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten                        // multiplier is calculated based on min & max normal mixer buffer size
153300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    // FIXME for FastMixer_Dynamic:
154300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    //  Supporting this option will require fixing HALs that can't handle large writes.
155300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    //  For example, one HAL implementation returns an error from a large write,
156300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    //  and another HAL implementation corrupts memory, possibly in the sample rate converter.
157300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    //  We could either fix the HAL implementations, or provide a wrapper that breaks
158300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    //  up large writes into smaller ones, and the wrapper would need to deal with scheduler.
159300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten} kUseFastMixer = FastMixer_Static;
160300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten
16128ed2f93324988767b5658eba7c1fa781a275183Glenn Kastenstatic uint32_t gScreenState; // incremented by 2 when screen state changes, bit 0 == 1 means "off"
16228ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten                              // AudioFlinger::setParameters() updates, other threads read w/o lock
16328ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten
164fd4e20c226eca185fc789de761beae64855bfbbbGlenn Kasten// Priorities for requestPriority
165fd4e20c226eca185fc789de761beae64855bfbbbGlenn Kastenstatic const int kPriorityAudioApp = 2;
166fd4e20c226eca185fc789de761beae64855bfbbbGlenn Kastenstatic const int kPriorityFastMixer = 3;
167fd4e20c226eca185fc789de761beae64855bfbbbGlenn Kasten
1683ed292031dc50c56110cdadb1e3778117e3be76aGlenn Kasten// IAudioFlinger::createTrack() reports back to client the total size of shared memory area
1693ed292031dc50c56110cdadb1e3778117e3be76aGlenn Kasten// for the track.  The client then sub-divides this into smaller buffers for its use.
1703ed292031dc50c56110cdadb1e3778117e3be76aGlenn Kasten// Currently the client uses double-buffering by default, but doesn't tell us about that.
1713ed292031dc50c56110cdadb1e3778117e3be76aGlenn Kasten// So for now we just assume that client is double-buffered.
172c3ae93f21280859086ae371428ffd32f39e76d50Glenn Kasten// FIXME It would be better for client to tell AudioFlinger whether it wants double-buffering or
173c3ae93f21280859086ae371428ffd32f39e76d50Glenn Kasten// N-buffering, so AudioFlinger could allocate the right amount of memory.
1743ed292031dc50c56110cdadb1e3778117e3be76aGlenn Kasten// See the client's minBufCount and mNotificationFramesAct calculations for details.
1753ed292031dc50c56110cdadb1e3778117e3be76aGlenn Kastenstatic const int kFastTrackMultiplier = 2;
1763ed292031dc50c56110cdadb1e3778117e3be76aGlenn Kasten
17765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
17865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
179d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten#ifdef ADD_BATTERY_DATA
1809ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang// To collect the amplifier usage
1819ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wangstatic void addBatteryData(uint32_t params) {
18225b248eb52a0a16adaef6b79c9d92cb88b9a2bc2Glenn Kasten    sp<IMediaPlayerService> service = IMediaDeathNotifier::getMediaPlayerService();
18325b248eb52a0a16adaef6b79c9d92cb88b9a2bc2Glenn Kasten    if (service == NULL) {
18425b248eb52a0a16adaef6b79c9d92cb88b9a2bc2Glenn Kasten        // it already logged
1859ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        return;
1869ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    }
1879ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
1889ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    service->addBatteryData(params);
1899ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang}
190d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten#endif
1919ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
192f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurentstatic int load_audio_interface(const char *if_name, audio_hw_device_t **dev)
193799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin{
194f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    const hw_module_t *mod;
195799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    int rc;
196799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
197f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);
198f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    ALOGE_IF(rc, "%s couldn't load audio hw module %s.%s (%s)", __func__,
199f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent                 AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
200f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    if (rc) {
201799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        goto out;
202f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    }
203f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    rc = audio_hw_device_open(mod, dev);
204f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    ALOGE_IF(rc, "%s couldn't open audio hw device in %s.%s (%s)", __func__,
205f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent                 AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
206f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    if (rc) {
207799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        goto out;
208f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    }
209f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    if ((*dev)->common.version != AUDIO_DEVICE_API_VERSION_CURRENT) {
210f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        ALOGE("%s wrong audio hw device version %04x", __func__, (*dev)->common.version);
211f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        rc = BAD_VALUE;
212f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        goto out;
213f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    }
214799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    return 0;
215799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
216799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavinout:
217799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    *dev = NULL;
218799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    return rc;
219799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin}
220799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
22165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
22265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
22365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::AudioFlinger()
22465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    : BnAudioFlinger(),
2254ff14bae91075eb274eb1c2975982358946e7e63John Grossman      mPrimaryHardwareDev(NULL),
2267d6c35bf132a46c0a8a9826491882495fc98bd8cGlenn Kasten      mHardwareStatus(AUDIO_HW_IDLE),
2274ff14bae91075eb274eb1c2975982358946e7e63John Grossman      mMasterVolume(1.0f),
2284ff14bae91075eb274eb1c2975982358946e7e63John Grossman      mMasterMute(false),
2294ff14bae91075eb274eb1c2975982358946e7e63John Grossman      mNextUniqueId(1),
2304ff14bae91075eb274eb1c2975982358946e7e63John Grossman      mMode(AUDIO_MODE_INVALID),
2314ff14bae91075eb274eb1c2975982358946e7e63John Grossman      mBtNrecIsOff(false)
23265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
2335a61d2f277af3098fc10b2881babca16391362daDima Zavin}
2345a61d2f277af3098fc10b2881babca16391362daDima Zavin
2355a61d2f277af3098fc10b2881babca16391362daDima Zavinvoid AudioFlinger::onFirstRef()
2365a61d2f277af3098fc10b2881babca16391362daDima Zavin{
237799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    int rc = 0;
238fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
239935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent    Mutex::Autolock _l(mLock);
240935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent
241799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    /* TODO: move all this work into an Init() function */
2424ff14bae91075eb274eb1c2975982358946e7e63John Grossman    char val_str[PROPERTY_VALUE_MAX] = { 0 };
2434ff14bae91075eb274eb1c2975982358946e7e63John Grossman    if (property_get("ro.audio.flinger_standbytime_ms", val_str, NULL) >= 0) {
2444ff14bae91075eb274eb1c2975982358946e7e63John Grossman        uint32_t int_val;
2454ff14bae91075eb274eb1c2975982358946e7e63John Grossman        if (1 == sscanf(val_str, "%u", &int_val)) {
2464ff14bae91075eb274eb1c2975982358946e7e63John Grossman            mStandbyTimeInNsecs = milliseconds(int_val);
2474ff14bae91075eb274eb1c2975982358946e7e63John Grossman            ALOGI("Using %u mSec as standby time.", int_val);
2484ff14bae91075eb274eb1c2975982358946e7e63John Grossman        } else {
2494ff14bae91075eb274eb1c2975982358946e7e63John Grossman            mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;
2504ff14bae91075eb274eb1c2975982358946e7e63John Grossman            ALOGI("Using default %u mSec as standby time.",
2514ff14bae91075eb274eb1c2975982358946e7e63John Grossman                    (uint32_t)(mStandbyTimeInNsecs / 1000000));
2524ff14bae91075eb274eb1c2975982358946e7e63John Grossman        }
2534ff14bae91075eb274eb1c2975982358946e7e63John Grossman    }
25465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
255a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    mMode = AUDIO_MODE_NORMAL;
25665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
25765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
25865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::~AudioFlinger()
25965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
26065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    while (!mRecordThreads.isEmpty()) {
261c3ae93f21280859086ae371428ffd32f39e76d50Glenn Kasten        // closeInput_nonvirtual() will remove specified entry from mRecordThreads
262d96c5724818fb47917bb5e7abe37799735e1ec0eGlenn Kasten        closeInput_nonvirtual(mRecordThreads.keyAt(0));
26365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
26465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    while (!mPlaybackThreads.isEmpty()) {
265c3ae93f21280859086ae371428ffd32f39e76d50Glenn Kasten        // closeOutput_nonvirtual() will remove specified entry from mPlaybackThreads
266d96c5724818fb47917bb5e7abe37799735e1ec0eGlenn Kasten        closeOutput_nonvirtual(mPlaybackThreads.keyAt(0));
26765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
268799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
2692b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten    for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
2702b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten        // no mHardwareLock needed, as there are no other references to this
271a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        audio_hw_device_close(mAudioHwDevs.valueAt(i)->hwDevice());
272a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        delete mAudioHwDevs.valueAt(i);
27365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
27465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
27565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
276a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurentstatic const char * const audio_interfaces[] = {
277a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    AUDIO_HARDWARE_MODULE_ID_PRIMARY,
278a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    AUDIO_HARDWARE_MODULE_ID_A2DP,
279a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    AUDIO_HARDWARE_MODULE_ID_USB,
280a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent};
281a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent#define ARRAY_SIZE(x) (sizeof((x))/sizeof(((x)[0])))
282a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
283ee578c0330319f04a48bccbdb26b53fea0388d04John GrossmanAudioFlinger::AudioHwDevice* AudioFlinger::findSuitableHwDev_l(
284ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        audio_module_handle_t module,
285ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        audio_devices_t devices)
286799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin{
287a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    // if module is 0, the request comes from an old policy manager and we should load
288a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    // well known modules
289a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    if (module == 0) {
290a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        ALOGW("findSuitableHwDev_l() loading well know audio hw modules");
291a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        for (size_t i = 0; i < ARRAY_SIZE(audio_interfaces); i++) {
292a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            loadHwModule_l(audio_interfaces[i]);
293a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        }
294f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent        // then try to find a module supporting the requested device.
295f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent        for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
296f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent            AudioHwDevice *audioHwDevice = mAudioHwDevs.valueAt(i);
297f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent            audio_hw_device_t *dev = audioHwDevice->hwDevice();
298f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent            if ((dev->get_supported_devices != NULL) &&
299f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent                    (dev->get_supported_devices(dev) & devices) == devices)
300f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent                return audioHwDevice;
301f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent        }
302a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    } else {
303a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        // check a match for the requested module handle
304ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        AudioHwDevice *audioHwDevice = mAudioHwDevs.valueFor(module);
305ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        if (audioHwDevice != NULL) {
306ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman            return audioHwDevice;
307a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        }
308a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    }
309a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
310799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    return NULL;
311799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin}
31265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
313be5f05e0fdfc4e3799653702187861a2afa072eeGlenn Kastenvoid AudioFlinger::dumpClients(int fd, const Vector<String16>& args)
31465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
31565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
31665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
31765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
31865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
31965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append("Clients:\n");
32065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < mClients.size(); ++i) {
32177c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten        sp<Client> client = mClients.valueAt(i).promote();
32277c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten        if (client != 0) {
32377c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten            snprintf(buffer, SIZE, "  pid: %d\n", client->pid());
32477c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten            result.append(buffer);
32565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
32665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
3273a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen
3283a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    result.append("Global session refs:\n");
329012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten    result.append(" session pid count\n");
3303a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    for (size_t i = 0; i < mAudioSessionRefs.size(); i++) {
3313a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        AudioSessionRef *r = mAudioSessionRefs[i];
332012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten        snprintf(buffer, SIZE, " %7d %3d %3d\n", r->mSessionid, r->mPid, r->mCnt);
3333a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        result.append(buffer);
3343a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    }
33565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
33665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
33765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
33865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
339be5f05e0fdfc4e3799653702187861a2afa072eeGlenn Kastenvoid AudioFlinger::dumpInternals(int fd, const Vector<String16>& args)
34065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
34165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
34265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
34365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
344a4454b4765c5905f14186893b0688be375642283Glenn Kasten    hardware_call_state hardwareStatus = mHardwareStatus;
34565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3464ff14bae91075eb274eb1c2975982358946e7e63John Grossman    snprintf(buffer, SIZE, "Hardware status: %d\n"
3474ff14bae91075eb274eb1c2975982358946e7e63John Grossman                           "Standby Time mSec: %u\n",
3484ff14bae91075eb274eb1c2975982358946e7e63John Grossman                            hardwareStatus,
3494ff14bae91075eb274eb1c2975982358946e7e63John Grossman                            (uint32_t)(mStandbyTimeInNsecs / 1000000));
35065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
35165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
35265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
35365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
354be5f05e0fdfc4e3799653702187861a2afa072eeGlenn Kastenvoid AudioFlinger::dumpPermissionDenial(int fd, const Vector<String16>& args)
35565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
35665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
35765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
35865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
35965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "Permission Denial: "
36065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            "can't dump AudioFlinger from pid=%d, uid=%d\n",
36165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            IPCThreadState::self()->getCallingPid(),
36265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            IPCThreadState::self()->getCallingUid());
36365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
36465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
36565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
36665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
36765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic bool tryLock(Mutex& mutex)
36865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
36965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool locked = false;
37065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < kDumpLockRetries; ++i) {
37165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mutex.tryLock() == NO_ERROR) {
37265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            locked = true;
37365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
37465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
3757dede876998ff56351d495ec3a798c1b131193e8Glenn Kasten        usleep(kDumpLockSleepUs);
37665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
37765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return locked;
37865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
37965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
38065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::dump(int fd, const Vector<String16>& args)
38165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
38244deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten    if (!dumpAllowed()) {
38365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        dumpPermissionDenial(fd, args);
38465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
38565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // get state of hardware lock
38665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        bool hardwareLocked = tryLock(mHardwareLock);
38765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!hardwareLocked) {
38865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            String8 result(kHardwareLockedString);
38965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            write(fd, result.string(), result.size());
39065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
39165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mHardwareLock.unlock();
39265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
39365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
39465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        bool locked = tryLock(mLock);
39565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
39665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // failed to lock - AudioFlinger is probably deadlocked
39765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!locked) {
39865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            String8 result(kDeadlockedString);
39965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            write(fd, result.string(), result.size());
40065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
40165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
40265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        dumpClients(fd, args);
40365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        dumpInternals(fd, args);
40465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
40565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // dump playback threads
40665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
40765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mPlaybackThreads.valueAt(i)->dump(fd, args);
40865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
40965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
41065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // dump record threads
41165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (size_t i = 0; i < mRecordThreads.size(); i++) {
41265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mRecordThreads.valueAt(i)->dump(fd, args);
41365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
41465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
415799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        // dump all hardware devs
416799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
417a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice();
418799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin            dev->dump(dev, fd);
41965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
420d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten
421d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        // dump the serially shared record tee sink
422d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        if (mRecordTeeSource != 0) {
423d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            dumpTee(fd, mRecordTeeSource);
424d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        }
425d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten
426d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        if (locked) {
427d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten            mLock.unlock();
428d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        }
42965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
43065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
43165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
43265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
43398ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kastensp<AudioFlinger::Client> AudioFlinger::registerPid_l(pid_t pid)
43498ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten{
43598ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    // If pid is already in the mClients wp<> map, then use that entry
43698ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    // (for which promote() is always != 0), otherwise create a new entry and Client.
43798ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    sp<Client> client = mClients.valueFor(pid).promote();
43898ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    if (client == 0) {
43998ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten        client = new Client(this, pid);
44098ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten        mClients.add(pid, client);
44198ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    }
44298ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten
44398ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    return client;
44498ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten}
44565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
44665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// IAudioFlinger interface
44765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
44865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
44965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansp<IAudioTrack> AudioFlinger::createTrack(
45065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        pid_t pid,
451fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten        audio_stream_type_t streamType,
45265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        uint32_t sampleRate,
45358f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten        audio_format_t format,
454254af180475346b6186b49c297f340c9c4817511Glenn Kasten        audio_channel_mask_t channelMask,
455e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten        size_t frameCount,
456e0b07179a48ee50fda931d2aa1b3c751d167e4d7Glenn Kasten        IAudioFlinger::track_flags_t *flags,
45765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        const sp<IMemory>& sharedBuffer,
45872ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten        audio_io_handle_t output,
4593acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten        pid_t tid,
46065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int *sessionId,
46165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status_t *status)
46265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
46365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<PlaybackThread::Track> track;
46465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<TrackHandle> trackHandle;
46565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<Client> client;
46665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t lStatus;
46765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int lSessionId;
46865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
469263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    // client AudioTrack::set already implements AUDIO_STREAM_DEFAULT => AUDIO_STREAM_MUSIC,
470263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    // but if someone uses binder directly they could bypass that and cause us to crash
471263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    if (uint32_t(streamType) >= AUDIO_STREAM_CNT) {
47229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("createTrack() invalid stream type %d", streamType);
47365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        lStatus = BAD_VALUE;
47465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        goto Exit;
47565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
47665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
47760a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten    // client is responsible for conversion of 8-bit PCM to 16-bit PCM,
47860a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten    // and we don't yet support 8.24 or 32-bit PCM
47960a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten    if (audio_is_linear_pcm(format) && format != AUDIO_FORMAT_PCM_16_BIT) {
48060a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten        ALOGE("createTrack() invalid format %d", format);
48160a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten        lStatus = BAD_VALUE;
48260a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten        goto Exit;
48360a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten    }
48460a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten
48565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    {
48665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock _l(mLock);
48765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        PlaybackThread *thread = checkPlaybackThread_l(output);
48839e94f8f723d445447fdee0822291e664b631f60Eric Laurent        PlaybackThread *effectThread = NULL;
48965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (thread == NULL) {
49029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("unknown output thread");
49165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            lStatus = BAD_VALUE;
49265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            goto Exit;
49365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
49465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
49598ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten        client = registerPid_l(pid);
49665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("createTrack() sessionId: %d", (sessionId == NULL) ? -2 : *sessionId);
498fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        if (sessionId != NULL && *sessionId != AUDIO_SESSION_OUTPUT_MIX) {
499f436fdcf93bd417fd3c9d2a8b19fd221d894b5e3Eric Laurent            // check if an effect chain with the same session ID is present on another
500f436fdcf93bd417fd3c9d2a8b19fd221d894b5e3Eric Laurent            // output thread and move it here.
501de070137f11d346fba77605bd76a44c040a618fcEric Laurent            for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
50239e94f8f723d445447fdee0822291e664b631f60Eric Laurent                sp<PlaybackThread> t = mPlaybackThreads.valueAt(i);
50339e94f8f723d445447fdee0822291e664b631f60Eric Laurent                if (mPlaybackThreads.keyAt(i) != output) {
50439e94f8f723d445447fdee0822291e664b631f60Eric Laurent                    uint32_t sessions = t->hasAudioSession(*sessionId);
50539e94f8f723d445447fdee0822291e664b631f60Eric Laurent                    if (sessions & PlaybackThread::EFFECT_SESSION) {
50639e94f8f723d445447fdee0822291e664b631f60Eric Laurent                        effectThread = t.get();
507f436fdcf93bd417fd3c9d2a8b19fd221d894b5e3Eric Laurent                        break;
50839e94f8f723d445447fdee0822291e664b631f60Eric Laurent                    }
509de070137f11d346fba77605bd76a44c040a618fcEric Laurent                }
510de070137f11d346fba77605bd76a44c040a618fcEric Laurent            }
51165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            lSessionId = *sessionId;
51265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
513de070137f11d346fba77605bd76a44c040a618fcEric Laurent            // if no audio session id is provided, create one here
5147c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            lSessionId = nextUniqueId();
51565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (sessionId != NULL) {
51665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                *sessionId = lSessionId;
51765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
51865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
5193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("createTrack() lSessionId: %d", lSessionId);
52065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
52165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        track = thread->createTrack_l(client, streamType, sampleRate, format,
5223acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten                channelMask, frameCount, sharedBuffer, lSessionId, flags, tid, &lStatus);
52339e94f8f723d445447fdee0822291e664b631f60Eric Laurent
52439e94f8f723d445447fdee0822291e664b631f60Eric Laurent        // move effect chain to this output thread if an effect on same session was waiting
52539e94f8f723d445447fdee0822291e664b631f60Eric Laurent        // for a track to be created
52639e94f8f723d445447fdee0822291e664b631f60Eric Laurent        if (lStatus == NO_ERROR && effectThread != NULL) {
52739e94f8f723d445447fdee0822291e664b631f60Eric Laurent            Mutex::Autolock _dl(thread->mLock);
52839e94f8f723d445447fdee0822291e664b631f60Eric Laurent            Mutex::Autolock _sl(effectThread->mLock);
52939e94f8f723d445447fdee0822291e664b631f60Eric Laurent            moveEffectChain_l(lSessionId, effectThread, thread, true);
53039e94f8f723d445447fdee0822291e664b631f60Eric Laurent        }
531a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
532a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        // Look for sync events awaiting for a session to be used.
533a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        for (int i = 0; i < (int)mPendingSyncEvents.size(); i++) {
534a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent            if (mPendingSyncEvents[i]->triggerSession() == lSessionId) {
535a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                if (thread->isValidSyncEvent(mPendingSyncEvents[i])) {
5362986460984580833161bdaabc7f17da1005a8961Eric Laurent                    if (lStatus == NO_ERROR) {
537d23eedca9b5a1812891c05d89850ab7ee707040dGlenn Kasten                        (void) track->setSyncEvent(mPendingSyncEvents[i]);
5382986460984580833161bdaabc7f17da1005a8961Eric Laurent                    } else {
5392986460984580833161bdaabc7f17da1005a8961Eric Laurent                        mPendingSyncEvents[i]->cancel();
5402986460984580833161bdaabc7f17da1005a8961Eric Laurent                    }
541a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                    mPendingSyncEvents.removeAt(i);
542a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                    i--;
543a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                }
544a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent            }
545a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        }
54665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
54765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (lStatus == NO_ERROR) {
54865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        trackHandle = new TrackHandle(track);
54965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
55065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // remove local strong reference to Client before deleting the Track so that the Client
55165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // destructor is called by the TrackBase destructor with mLock held
55265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        client.clear();
55365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        track.clear();
55465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
55565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
55665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianExit:
557e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    if (status != NULL) {
55865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        *status = lStatus;
55965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
56065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return trackHandle;
56165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
56265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
56372ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenuint32_t AudioFlinger::sampleRate(audio_io_handle_t output) const
56465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
56565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
56665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *thread = checkPlaybackThread_l(output);
56765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread == NULL) {
5685ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("sampleRate() unknown thread %d", output);
56965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return 0;
57065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
57165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return thread->sampleRate();
57265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
57365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
57472ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenint AudioFlinger::channelCount(audio_io_handle_t output) const
57565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
57665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
57765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *thread = checkPlaybackThread_l(output);
57865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread == NULL) {
5795ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("channelCount() unknown thread %d", output);
58065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return 0;
58165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
58265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return thread->channelCount();
58365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
58465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
58572ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenaudio_format_t AudioFlinger::format(audio_io_handle_t output) const
58665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
58765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
58865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *thread = checkPlaybackThread_l(output);
58965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread == NULL) {
5905ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("format() unknown thread %d", output);
59158f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten        return AUDIO_FORMAT_INVALID;
59265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
59365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return thread->format();
59465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
59565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
59672ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastensize_t AudioFlinger::frameCount(audio_io_handle_t output) const
59765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
59865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
59965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *thread = checkPlaybackThread_l(output);
60065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread == NULL) {
6015ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("frameCount() unknown thread %d", output);
60265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return 0;
60365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
60458912562617941964939a4182cda71eaeb153d4bGlenn Kasten    // FIXME currently returns the normal mixer's frame count to avoid confusing legacy callers;
60558912562617941964939a4182cda71eaeb153d4bGlenn Kasten    //       should examine all callers and fix them to handle smaller counts
60665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return thread->frameCount();
60765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
60865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
60972ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenuint32_t AudioFlinger::latency(audio_io_handle_t output) const
61065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
61165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
61265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *thread = checkPlaybackThread_l(output);
61365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread == NULL) {
6145ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("latency() unknown thread %d", output);
61565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return 0;
61665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
61765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return thread->latency();
61865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
61965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
62065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::setMasterVolume(float value)
62165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
622a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    status_t ret = initCheck();
623a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    if (ret != NO_ERROR) {
624a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        return ret;
625a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    }
626a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent
62765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
62865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
62965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
63065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
63165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
632a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    Mutex::Autolock _l(mLock);
633ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    mMasterVolume = value;
634a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
635ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // Set master volume in the HALs which support it.
636ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
637ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        AutoMutex lock(mHardwareLock);
638ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        AudioHwDevice *dev = mAudioHwDevs.valueAt(i);
6394ff14bae91075eb274eb1c2975982358946e7e63John Grossman
640ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
641ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        if (dev->canSetMasterVolume()) {
642ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman            dev->hwDevice()->set_master_volume(dev->hwDevice(), value);
643935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent        }
644ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mHardwareStatus = AUDIO_HW_IDLE;
64565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
64665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
647ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // Now set the master volume in each playback thread.  Playback threads
648ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // assigned to HALs which do not have master volume support will apply
649ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // master volume during the mix operation.  Threads with HALs which do
650ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // support master volume will simply ignore the setting.
6518d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    for (size_t i = 0; i < mPlaybackThreads.size(); i++)
652ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mPlaybackThreads.valueAt(i)->setMasterVolume(value);
65365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
65465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
65565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
65665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
657f78aee70d15daf4690de7e7b4983ee68b0d1381dGlenn Kastenstatus_t AudioFlinger::setMode(audio_mode_t mode)
65865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
659a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    status_t ret = initCheck();
660a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    if (ret != NO_ERROR) {
661a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        return ret;
662a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    }
66365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
66465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
66565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
66665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
66765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
668930f4caa1e311ef7ff538c421a324396157eb24fGlenn Kasten    if (uint32_t(mode) >= AUDIO_MODE_CNT) {
6695ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Illegal value: setMode(%d)", mode);
67065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return BAD_VALUE;
67165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
67265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
67365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    { // scope for the lock
67465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        AutoMutex lock(mHardwareLock);
675ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
67665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mHardwareStatus = AUDIO_HW_SET_MODE;
677ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        ret = dev->set_mode(dev, mode);
67865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mHardwareStatus = AUDIO_HW_IDLE;
67965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
68065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
68165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (NO_ERROR == ret) {
68265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock _l(mLock);
68365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mMode = mode;
6848d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten        for (size_t i = 0; i < mPlaybackThreads.size(); i++)
685e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten            mPlaybackThreads.valueAt(i)->setMode(mode);
68665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
68765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
68865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return ret;
68965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
69065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
69165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::setMicMute(bool state)
69265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
693a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    status_t ret = initCheck();
694a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    if (ret != NO_ERROR) {
695a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        return ret;
696a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    }
697a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent
69865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
69965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
70065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
70165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
70265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
70365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    AutoMutex lock(mHardwareLock);
704ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
70565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardwareStatus = AUDIO_HW_SET_MIC_MUTE;
706ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    ret = dev->set_mic_mute(dev, state);
70765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardwareStatus = AUDIO_HW_IDLE;
70865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return ret;
70965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
71065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
71165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool AudioFlinger::getMicMute() const
71265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
713a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    status_t ret = initCheck();
714a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    if (ret != NO_ERROR) {
715a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        return false;
716a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    }
717a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent
718fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    bool state = AUDIO_MODE_INVALID;
7192b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten    AutoMutex lock(mHardwareLock);
720ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
72165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardwareStatus = AUDIO_HW_GET_MIC_MUTE;
722ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    dev->get_mic_mute(dev, &state);
72365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardwareStatus = AUDIO_HW_IDLE;
72465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return state;
72565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
72665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
72765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::setMasterMute(bool muted)
72865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
729d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman    status_t ret = initCheck();
730d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman    if (ret != NO_ERROR) {
731d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman        return ret;
732d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman    }
733d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman
73465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
73565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
73665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
73765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
73865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
739ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    Mutex::Autolock _l(mLock);
740ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    mMasterMute = muted;
741d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman
742ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // Set master mute in the HALs which support it.
743ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
744ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        AutoMutex lock(mHardwareLock);
745ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        AudioHwDevice *dev = mAudioHwDevs.valueAt(i);
746d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman
747ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE;
748ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        if (dev->canSetMasterMute()) {
749ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman            dev->hwDevice()->set_master_mute(dev->hwDevice(), muted);
750d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman        }
751ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mHardwareStatus = AUDIO_HW_IDLE;
752d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman    }
753d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman
754ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // Now set the master mute in each playback thread.  Playback threads
755ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // assigned to HALs which do not have master mute support will apply master
756ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // mute during the mix operation.  Threads with HALs which do support master
757ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // mute will simply ignore the setting.
7588d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    for (size_t i = 0; i < mPlaybackThreads.size(); i++)
759ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mPlaybackThreads.valueAt(i)->setMasterMute(muted);
76065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
76165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
76265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
76365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
76465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianfloat AudioFlinger::masterVolume() const
76565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
7669806710f5d6722cfc5783c7eca3512451a0f2035Glenn Kasten    Mutex::Autolock _l(mLock);
7679806710f5d6722cfc5783c7eca3512451a0f2035Glenn Kasten    return masterVolume_l();
76865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
76965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
77065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool AudioFlinger::masterMute() const
77165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
7729806710f5d6722cfc5783c7eca3512451a0f2035Glenn Kasten    Mutex::Autolock _l(mLock);
7739806710f5d6722cfc5783c7eca3512451a0f2035Glenn Kasten    return masterMute_l();
77465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
77565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7764ff14bae91075eb274eb1c2975982358946e7e63John Grossmanfloat AudioFlinger::masterVolume_l() const
7774ff14bae91075eb274eb1c2975982358946e7e63John Grossman{
7784ff14bae91075eb274eb1c2975982358946e7e63John Grossman    return mMasterVolume;
7794ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
7804ff14bae91075eb274eb1c2975982358946e7e63John Grossman
781d8f178d613821c3f61a5c5e391eb275339e526a9John Grossmanbool AudioFlinger::masterMute_l() const
782d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman{
783ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    return mMasterMute;
784d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman}
785d8f178d613821c3f61a5c5e391eb275339e526a9John Grossman
78672ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenstatus_t AudioFlinger::setStreamVolume(audio_stream_type_t stream, float value,
78772ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten        audio_io_handle_t output)
78865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
78965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
79065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
79165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
79265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
79365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
794263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
79529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("setStreamVolume() invalid stream %d", stream);
79665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return BAD_VALUE;
79765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
79865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
79965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    AutoMutex lock(mLock);
80065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *thread = NULL;
80165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (output) {
80265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        thread = checkPlaybackThread_l(output);
80365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (thread == NULL) {
80465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return BAD_VALUE;
80565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
80665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
80765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
80865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mStreamTypes[stream].volume = value;
80965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
81065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread == NULL) {
8118d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten        for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
812e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten            mPlaybackThreads.valueAt(i)->setStreamVolume(stream, value);
81365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
81465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
81565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        thread->setStreamVolume(stream, value);
81665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
81765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
81865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
81965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
82065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
821fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kastenstatus_t AudioFlinger::setStreamMute(audio_stream_type_t stream, bool muted)
82265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
82365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
82465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
82565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
82665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
82765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
828263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    if (uint32_t(stream) >= AUDIO_STREAM_CNT ||
829fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        uint32_t(stream) == AUDIO_STREAM_ENFORCED_AUDIBLE) {
83029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("setStreamMute() invalid stream %d", stream);
83165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return BAD_VALUE;
83265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
83365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
834935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent    AutoMutex lock(mLock);
83565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mStreamTypes[stream].mute = muted;
83665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
837e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        mPlaybackThreads.valueAt(i)->setStreamMute(stream, muted);
83865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
83965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
84065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
84165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
84272ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenfloat AudioFlinger::streamVolume(audio_stream_type_t stream, audio_io_handle_t output) const
84365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
844263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
84565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return 0.0f;
84665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
84765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
84865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    AutoMutex lock(mLock);
84965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    float volume;
85065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (output) {
85165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        PlaybackThread *thread = checkPlaybackThread_l(output);
85265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (thread == NULL) {
85365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return 0.0f;
85465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
85565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        volume = thread->streamVolume(stream);
85665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
8576637baae4244aec731c4014da72418d330636ae1Glenn Kasten        volume = streamVolume_l(stream);
85865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
85965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
86065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return volume;
86165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
86265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
863fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kastenbool AudioFlinger::streamMute(audio_stream_type_t stream) const
86465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
865263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
86665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return true;
86765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
86865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
8696637baae4244aec731c4014da72418d330636ae1Glenn Kasten    AutoMutex lock(mLock);
8706637baae4244aec731c4014da72418d330636ae1Glenn Kasten    return streamMute_l(stream);
87165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
87265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
87372ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenstatus_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs)
87465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
87523d82a9bc9a43b49ba684ba40875b91db310d3b9Glenn Kasten    ALOGV("setParameters(): io %d, keyvalue %s, tid %d, calling pid %d",
87665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            ioHandle, keyValuePairs.string(), gettid(), IPCThreadState::self()->getCallingPid());
87765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
87865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
87965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
88065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
88165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
88265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // ioHandle == 0 means the parameters are global to the audio hardware interface
88365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (ioHandle == 0) {
884a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        Mutex::Autolock _l(mLock);
885799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        status_t final_result = NO_ERROR;
8868abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten        {
887a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            AutoMutex lock(mHardwareLock);
888a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            mHardwareStatus = AUDIO_HW_SET_PARAMETER;
889a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
890a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice();
891a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                status_t result = dev->set_parameters(dev, keyValuePairs.string());
892a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                final_result = result ?: final_result;
893a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            }
894a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            mHardwareStatus = AUDIO_HW_IDLE;
8958abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten        }
89659bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent        // disable AEC and NS if the device is a BT SCO headset supporting those pre processings
89759bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent        AudioParameter param = AudioParameter(keyValuePairs);
89859bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent        String8 value;
89959bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent        if (param.get(String8(AUDIO_PARAMETER_KEY_BT_NREC), value) == NO_ERROR) {
900bee5337da7659b3b7128622ba1f42618b11df5beEric Laurent            bool btNrecIsOff = (value == AUDIO_PARAMETER_VALUE_OFF);
901bee5337da7659b3b7128622ba1f42618b11df5beEric Laurent            if (mBtNrecIsOff != btNrecIsOff) {
90259bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                for (size_t i = 0; i < mRecordThreads.size(); i++) {
90359bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                    sp<RecordThread> thread = mRecordThreads.valueAt(i);
904f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent                    audio_devices_t device = thread->inDevice();
905510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                    bool suspend = audio_is_bluetooth_sco_device(device) && btNrecIsOff;
906510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                    // collect all of the thread's session IDs
907510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                    KeyedVector<int, bool> ids = thread->sessionIds();
908510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                    // suspend effects associated with those session IDs
909510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                    for (size_t j = 0; j < ids.size(); ++j) {
910510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                        int sessionId = ids.keyAt(j);
91159bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                        thread->setEffectSuspended(FX_IID_AEC,
91259bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                                                   suspend,
913510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                                                   sessionId);
91459bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                        thread->setEffectSuspended(FX_IID_NS,
91559bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                                                   suspend,
916510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                                                   sessionId);
91759bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                    }
91859bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                }
919bee5337da7659b3b7128622ba1f42618b11df5beEric Laurent                mBtNrecIsOff = btNrecIsOff;
92059bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent            }
92159bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent        }
92228ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten        String8 screenState;
92328ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten        if (param.get(String8(AudioParameter::keyScreenState), screenState) == NO_ERROR) {
92428ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten            bool isOff = screenState == "off";
92528ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten            if (isOff != (gScreenState & 1)) {
92628ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten                gScreenState = ((gScreenState & ~1) + 2) | isOff;
92728ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten            }
92828ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten        }
929799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        return final_result;
93065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
93165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
93265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // hold a strong ref on thread in case closeOutput() or closeInput() is called
93365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // and the thread is exited once the lock is released
93465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<ThreadBase> thread;
93565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    {
93665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock _l(mLock);
93765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        thread = checkPlaybackThread_l(ioHandle);
938d5903ec1332630f2992a6f0d5ca69d13a185c665Glenn Kasten        if (thread == 0) {
93965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            thread = checkRecordThread_l(ioHandle);
9407fc9a6fdf146ded90b51c52f4a05d797294dcb85Glenn Kasten        } else if (thread == primaryPlaybackThread_l()) {
9417c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            // indicate output device change to all input threads for pre processing
9427c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            AudioParameter param = AudioParameter(keyValuePairs);
9437c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            int value;
94489d94e79dad032fb18ddc655e6068e4231d3f0aaEric Laurent            if ((param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) &&
94589d94e79dad032fb18ddc655e6068e4231d3f0aaEric Laurent                    (value != 0)) {
9467c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                for (size_t i = 0; i < mRecordThreads.size(); i++) {
9477c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                    mRecordThreads.valueAt(i)->setParameters(keyValuePairs);
9487c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                }
9497c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            }
95065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
95165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
9527378ca506e4e20c2b2d4e94a131cf1b95831adb5Glenn Kasten    if (thread != 0) {
9537378ca506e4e20c2b2d4e94a131cf1b95831adb5Glenn Kasten        return thread->setParameters(keyValuePairs);
95465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
95565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return BAD_VALUE;
95665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
95765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
95872ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn KastenString8 AudioFlinger::getParameters(audio_io_handle_t ioHandle, const String8& keys) const
95965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
96026dd66e8ea7a1abf28c33196fc77822f68a718afGlenn Kasten    ALOGVV("getParameters() io %d, keys %s, tid %d, calling pid %d",
96126dd66e8ea7a1abf28c33196fc77822f68a718afGlenn Kasten            ioHandle, keys.string(), gettid(), IPCThreadState::self()->getCallingPid());
96265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
963a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    Mutex::Autolock _l(mLock);
964a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
96565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (ioHandle == 0) {
966fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        String8 out_s8;
967fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
968799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
9698abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            char *s;
9708abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            {
9718abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            AutoMutex lock(mHardwareLock);
9728abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            mHardwareStatus = AUDIO_HW_GET_PARAMETER;
973a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice();
9748abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            s = dev->get_parameters(dev, keys.string());
9758abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            mHardwareStatus = AUDIO_HW_IDLE;
9768abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten            }
977ef7740be67a4d7b6b033ebed59c3d4a9c74a2c18John Grossman            out_s8 += String8(s ? s : "");
978799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin            free(s);
979799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        }
980fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        return out_s8;
98165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
98265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
98365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *playbackThread = checkPlaybackThread_l(ioHandle);
98465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (playbackThread != NULL) {
98565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return playbackThread->getParameters(keys);
98665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
98765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    RecordThread *recordThread = checkRecordThread_l(ioHandle);
98865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (recordThread != NULL) {
98965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return recordThread->getParameters(keys);
99065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
99165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return String8("");
99265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
99365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
994dd8104cc5367262f0e5f13df4e79f131e8d560bbGlenn Kastensize_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, audio_format_t format,
995dd8104cc5367262f0e5f13df4e79f131e8d560bbGlenn Kasten        audio_channel_mask_t channelMask) const
99665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
997a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    status_t ret = initCheck();
998a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    if (ret != NO_ERROR) {
999a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        return 0;
1000a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    }
1001a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent
10022b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten    AutoMutex lock(mHardwareLock);
10032b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten    mHardwareStatus = AUDIO_HW_GET_INPUT_BUFFER_SIZE;
1004f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    struct audio_config config = {
1005f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        sample_rate: sampleRate,
1006dd8104cc5367262f0e5f13df4e79f131e8d560bbGlenn Kasten        channel_mask: channelMask,
1007f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        format: format,
1008f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    };
1009ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
1010ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    size_t size = dev->get_input_buffer_size(dev, &config);
10112b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten    mHardwareStatus = AUDIO_HW_IDLE;
10122b213bc220768d2b984239511cd4554a96bc0079Glenn Kasten    return size;
101365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
101465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
101572ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenunsigned int AudioFlinger::getInputFramesLost(audio_io_handle_t ioHandle) const
101665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
101765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
101865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
101965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    RecordThread *recordThread = checkRecordThread_l(ioHandle);
102065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (recordThread != NULL) {
102165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return recordThread->getInputFramesLost();
102265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
102365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return 0;
102465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
102565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
102665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::setVoiceVolume(float value)
102765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
1028a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    status_t ret = initCheck();
1029a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    if (ret != NO_ERROR) {
1030a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent        return ret;
1031a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent    }
1032a1884f9e9ec3836683efd7eb333ee442e8bc9d56Eric Laurent
103365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
103465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!settingsAllowed()) {
103565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
103665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
103765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
103865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    AutoMutex lock(mHardwareLock);
1039ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
10408abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten    mHardwareStatus = AUDIO_HW_SET_VOICE_VOLUME;
1041ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    ret = dev->set_voice_volume(dev, value);
104265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardwareStatus = AUDIO_HW_IDLE;
104365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
104465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return ret;
104565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
104665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
104772ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenstatus_t AudioFlinger::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames,
104872ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten        audio_io_handle_t output) const
104965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
105065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t status;
105165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
105265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
105365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
105465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *playbackThread = checkPlaybackThread_l(output);
105565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (playbackThread != NULL) {
105665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return playbackThread->getRenderPosition(halFrames, dspFrames);
105765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
105865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
105965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return BAD_VALUE;
106065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
106165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
106265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)
106365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
106465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
106565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
106665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1067bb001926447d0b7dc71ca8bb3c9856f3136d8f4cGlenn Kasten    pid_t pid = IPCThreadState::self()->getCallingPid();
106865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mNotificationClients.indexOfKey(pid) < 0) {
106965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<NotificationClient> notificationClient = new NotificationClient(this,
107065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                                                            client,
107165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                                                            pid);
10723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("registerClient() client %p, pid %d", notificationClient.get(), pid);
107365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
107465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mNotificationClients.add(pid, notificationClient);
107565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
107665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<IBinder> binder = client->asBinder();
107765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        binder->linkToDeath(notificationClient);
107865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
107965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // the config change is always sent from playback or record threads to avoid deadlock
108065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // with AudioSystem::gLock
108165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
1082896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent            mPlaybackThreads.valueAt(i)->sendIoConfigEvent(AudioSystem::OUTPUT_OPENED);
108365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
108465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
108565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (size_t i = 0; i < mRecordThreads.size(); i++) {
1086896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent            mRecordThreads.valueAt(i)->sendIoConfigEvent(AudioSystem::INPUT_OPENED);
108765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
108865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
108965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
109065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
109165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::removeNotificationClient(pid_t pid)
109265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
109365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
109465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1095a3b09254d44cd8d66ec947abe547538c4cfeaa89Glenn Kasten    mNotificationClients.removeItem(pid);
10963a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen
10973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("%d died, releasing its sessions", pid);
10988d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    size_t num = mAudioSessionRefs.size();
10993a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    bool removed = false;
11008d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    for (size_t i = 0; i< num; ) {
11013a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        AudioSessionRef *ref = mAudioSessionRefs.itemAt(i);
1102012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten        ALOGV(" pid %d @ %d", ref->mPid, i);
1103012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten        if (ref->mPid == pid) {
1104012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten            ALOGV(" removing entry for pid %d session %d", pid, ref->mSessionid);
11053a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            mAudioSessionRefs.removeAt(i);
11063a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            delete ref;
11073a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            removed = true;
11083a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            num--;
11098d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten        } else {
11108d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten            i++;
11113a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        }
11123a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    }
11133a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    if (removed) {
11143a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        purgeStaleEffects_l();
11153a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    }
111665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
111765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
111865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// audioConfigChanged_l() must be called with AudioFlinger::mLock held
1119b81cc8c6f3eec9edb255ea99b6a6f243585b1e38Glenn Kastenvoid AudioFlinger::audioConfigChanged_l(int event, audio_io_handle_t ioHandle, const void *param2)
112065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
112165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    size_t size = mNotificationClients.size();
112265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < size; i++) {
112384afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten        mNotificationClients.valueAt(i)->audioFlingerClient()->ioConfigChanged(event, ioHandle,
112484afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten                                                                               param2);
112565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
112665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
112765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
112865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// removeClient_l() must be called with AudioFlinger::mLock held
112965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::removeClient_l(pid_t pid)
113065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
113185ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten    ALOGV("removeClient_l() pid %d, tid %d, calling tid %d", pid, gettid(),
113285ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten            IPCThreadState::self()->getCallingPid());
113365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mClients.removeItem(pid);
113465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
113565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1136717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent// getEffectThread_l() must be called with AudioFlinger::mLock held
1137717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurentsp<AudioFlinger::PlaybackThread> AudioFlinger::getEffectThread_l(int sessionId, int EffectId)
1138717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent{
1139717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent    sp<PlaybackThread> thread;
1140717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent
1141717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
1142717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent        if (mPlaybackThreads.valueAt(i)->getEffect(sessionId, EffectId) != 0) {
1143717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent            ALOG_ASSERT(thread == 0);
1144717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent            thread = mPlaybackThreads.valueAt(i);
1145717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent        }
1146717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent    }
1147717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent
1148717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent    return thread;
1149717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent}
115065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
115165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
115265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
115372ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn KastenAudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
1154f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent        audio_devices_t outDevice, audio_devices_t inDevice, type_t type)
1155c3ae93f21280859086ae371428ffd32f39e76d50Glenn Kasten    :   Thread(false /*canCallJava*/),
115623bb8becff20449a9b1647d5a1a99b14c83f0cceGlenn Kasten        mType(type),
115758912562617941964939a4182cda71eaeb153d4bGlenn Kasten        mAudioFlinger(audioFlinger), mSampleRate(0), mFrameCount(0), mNormalFrameCount(0),
115884afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten        // mChannelMask
115984afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten        mChannelCount(0),
116084afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten        mFrameSize(1), mFormat(AUDIO_FORMAT_INVALID),
116184afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten        mParamStatus(NO_ERROR),
1162f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent        mStandby(false), mOutDevice(outDevice), mInDevice(inDevice),
1163f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent        mAudioSource(AUDIO_SOURCE_DEFAULT), mId(id),
1164c3ae93f21280859086ae371428ffd32f39e76d50Glenn Kasten        // mName will be set by concrete (non-virtual) subclass
116584afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten        mDeathRecipient(new PMDeathRecipient(this))
116665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
116765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
116865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
116965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::ThreadBase::~ThreadBase()
117065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
117165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mParamCond.broadcast();
1172feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    // do not lock the mutex in destructor
1173feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    releaseWakeLock_l();
11749d18ec574f5d847a86a21594ac39394ef5b108fcEric Laurent    if (mPowerManager != 0) {
11759d18ec574f5d847a86a21594ac39394ef5b108fcEric Laurent        sp<IBinder> binder = mPowerManager->asBinder();
11769d18ec574f5d847a86a21594ac39394ef5b108fcEric Laurent        binder->unlinkToDeath(mDeathRecipient);
11779d18ec574f5d847a86a21594ac39394ef5b108fcEric Laurent    }
117865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
117965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
118065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::ThreadBase::exit()
118165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
11823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("ThreadBase::exit");
11832bfc6b42b3733c12485dd51ed95191956abc3e4eJean-Michel Trivi    // do any cleanup required for exit to succeed
11842bfc6b42b3733c12485dd51ed95191956abc3e4eJean-Michel Trivi    preExit();
118565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    {
1186b28686f95daee16edeb5f39af2cd5274ac3dc99fGlenn Kasten        // This lock prevents the following race in thread (uniprocessor for illustration):
1187b28686f95daee16edeb5f39af2cd5274ac3dc99fGlenn Kasten        //  if (!exitPending()) {
1188b28686f95daee16edeb5f39af2cd5274ac3dc99fGlenn Kasten        //      // context switch from here to exit()
1189b28686f95daee16edeb5f39af2cd5274ac3dc99fGlenn Kasten        //      // exit() calls requestExit(), what exitPending() observes
1190b28686f95daee16edeb5f39af2cd5274ac3dc99fGlenn Kasten        //      // exit() calls signal(), which is dropped since no waiters
1191b28686f95daee16edeb5f39af2cd5274ac3dc99fGlenn Kasten        //      // context switch back from exit() to here
1192b28686f95daee16edeb5f39af2cd5274ac3dc99fGlenn Kasten        //      mWaitWorkCV.wait(...);
1193b28686f95daee16edeb5f39af2cd5274ac3dc99fGlenn Kasten        //      // now thread is hung
1194b28686f95daee16edeb5f39af2cd5274ac3dc99fGlenn Kasten        //  }
1195a7d8d6fc5e102a08b262a1b78aa1abeeb097d9e4Glenn Kasten        AutoMutex lock(mLock);
119665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        requestExit();
1197b6ba2fd0d61a4844c153e17843fbe2c841c4bf57Eric Laurent        mWaitWorkCV.broadcast();
119865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
1199b28686f95daee16edeb5f39af2cd5274ac3dc99fGlenn Kasten    // When Thread::requestExitAndWait is made virtual and this method is renamed to
1200b28686f95daee16edeb5f39af2cd5274ac3dc99fGlenn Kasten    // "virtual status_t requestExitAndWait()", replace by "return Thread::requestExitAndWait();"
120165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    requestExitAndWait();
120265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
120365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
120465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::ThreadBase::setParameters(const String8& keyValuePairs)
120565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
120665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t status;
120765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
12083856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("ThreadBase::setParameters() %s", keyValuePairs.string());
120965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
121065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
121165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mNewParameters.add(keyValuePairs);
121265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mWaitWorkCV.signal();
121365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // wait condition with timeout in case the thread loop has exited
121465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // before the request could be processed
12157dede876998ff56351d495ec3a798c1b131193e8Glenn Kasten    if (mParamCond.waitRelative(mLock, kSetParametersTimeoutNs) == NO_ERROR) {
121665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status = mParamStatus;
121765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mWaitWorkCV.signal();
121865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
121965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status = TIMED_OUT;
122065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
122165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return status;
122265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
122365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1224896adcd3ae6a1c7010e526327eff54e16179987bEric Laurentvoid AudioFlinger::ThreadBase::sendIoConfigEvent(int event, int param)
122565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
122665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
1227896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent    sendIoConfigEvent_l(event, param);
122865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
122965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1230896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent// sendIoConfigEvent_l() must be called with ThreadBase::mLock held
1231896adcd3ae6a1c7010e526327eff54e16179987bEric Laurentvoid AudioFlinger::ThreadBase::sendIoConfigEvent_l(int event, int param)
123265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
1233896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent    IoConfigEvent *ioEvent = new IoConfigEvent(event, param);
1234896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent    mConfigEvents.add(static_cast<ConfigEvent *>(ioEvent));
123585ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten    ALOGV("sendIoConfigEvent() num events %d event %d, param %d", mConfigEvents.size(), event,
123685ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten            param);
1237896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent    mWaitWorkCV.signal();
1238896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent}
1239896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent
1240896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent// sendPrioConfigEvent_l() must be called with ThreadBase::mLock held
1241896adcd3ae6a1c7010e526327eff54e16179987bEric Laurentvoid AudioFlinger::ThreadBase::sendPrioConfigEvent_l(pid_t pid, pid_t tid, int32_t prio)
1242896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent{
1243896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent    PrioConfigEvent *prioEvent = new PrioConfigEvent(pid, tid, prio);
1244896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent    mConfigEvents.add(static_cast<ConfigEvent *>(prioEvent));
1245896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent    ALOGV("sendPrioConfigEvent_l() num events %d pid %d, tid %d prio %d",
1246896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent          mConfigEvents.size(), pid, tid, prio);
124765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mWaitWorkCV.signal();
124865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
124965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
125065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::ThreadBase::processConfigEvents()
125165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
125265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mLock.lock();
1253e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    while (!mConfigEvents.isEmpty()) {
12543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("processConfigEvents() remaining events %d", mConfigEvents.size());
1255896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent        ConfigEvent *event = mConfigEvents[0];
125665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mConfigEvents.removeAt(0);
125765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // release mLock before locking AudioFlinger mLock: lock order is always
125865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // AudioFlinger then ThreadBase to avoid cross deadlock
125965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mLock.unlock();
1260896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent        switch(event->type()) {
1261896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent            case CFG_EVENT_PRIO: {
1262896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent                PrioConfigEvent *prioEvent = static_cast<PrioConfigEvent *>(event);
1263896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent                int err = requestPriority(prioEvent->pid(), prioEvent->tid(), prioEvent->prio());
1264896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent                if (err != 0) {
126585ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                    ALOGW("Policy SCHED_FIFO priority %d is unavailable for pid %d tid %d; "
126685ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                          "error %d",
1267896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent                          prioEvent->prio(), prioEvent->pid(), prioEvent->tid(), err);
1268896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent                }
1269896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent            } break;
1270896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent            case CFG_EVENT_IO: {
1271896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent                IoConfigEvent *ioEvent = static_cast<IoConfigEvent *>(event);
1272896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent                mAudioFlinger->mLock.lock();
1273896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent                audioConfigChanged_l(ioEvent->event(), ioEvent->param());
1274896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent                mAudioFlinger->mLock.unlock();
1275896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent            } break;
1276896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent            default:
1277896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent                ALOGE("processConfigEvents() unknown event type %d", event->type());
1278896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent                break;
1279896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent        }
1280896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent        delete event;
128165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mLock.lock();
128265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
128365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mLock.unlock();
128465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
128565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1286be5f05e0fdfc4e3799653702187861a2afa072eeGlenn Kastenvoid AudioFlinger::ThreadBase::dumpBase(int fd, const Vector<String16>& args)
128765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
128865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
128965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
129065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
129165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
129265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool locked = tryLock(mLock);
129365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!locked) {
129465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        snprintf(buffer, SIZE, "thread %p maybe dead locked\n", this);
129565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        write(fd, buffer, strlen(buffer));
129665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
129765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1298612bbb57c59397a540e96f06bdd16e437a583af5Eric Laurent    snprintf(buffer, SIZE, "io handle: %d\n", mId);
1299612bbb57c59397a540e96f06bdd16e437a583af5Eric Laurent    result.append(buffer);
1300612bbb57c59397a540e96f06bdd16e437a583af5Eric Laurent    snprintf(buffer, SIZE, "TID: %d\n", getTid());
1301612bbb57c59397a540e96f06bdd16e437a583af5Eric Laurent    result.append(buffer);
130265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "standby: %d\n", mStandby);
130365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
13043b16c766d1ae2cfd8487e8ffb2b23936fc0a8e17Glenn Kasten    snprintf(buffer, SIZE, "Sample rate: %u\n", mSampleRate);
130565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
130658912562617941964939a4182cda71eaeb153d4bGlenn Kasten    snprintf(buffer, SIZE, "HAL frame count: %d\n", mFrameCount);
130758912562617941964939a4182cda71eaeb153d4bGlenn Kasten    result.append(buffer);
130858912562617941964939a4182cda71eaeb153d4bGlenn Kasten    snprintf(buffer, SIZE, "Normal frame count: %d\n", mNormalFrameCount);
130965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
131065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "Channel Count: %d\n", mChannelCount);
131165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
13120d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi    snprintf(buffer, SIZE, "Channel Mask: 0x%08x\n", mChannelMask);
13130d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi    result.append(buffer);
131465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "Format: %d\n", mFormat);
131565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
1316b9980659501d0428d65d8292f3c32da69d37fbd2Glenn Kasten    snprintf(buffer, SIZE, "Frame size: %u\n", mFrameSize);
131765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
131865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
131965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "\nPending setParameters commands: \n");
132065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
132165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(" Index Command");
132265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < mNewParameters.size(); ++i) {
132365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        snprintf(buffer, SIZE, "\n %02d    ", i);
132465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        result.append(buffer);
132565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        result.append(mNewParameters[i]);
132665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
132765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
132865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "\n\nPending config events: \n");
132965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
133065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < mConfigEvents.size(); i++) {
1331896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent        mConfigEvents[i]->dump(buffer, SIZE);
133265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        result.append(buffer);
133365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
133465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append("\n");
133565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
133665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
133765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
133865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (locked) {
133965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mLock.unlock();
134065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
134165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
134265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1343be5f05e0fdfc4e3799653702187861a2afa072eeGlenn Kastenvoid AudioFlinger::ThreadBase::dumpEffectChains(int fd, const Vector<String16>& args)
13441d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent{
13451d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent    const size_t SIZE = 256;
13461d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent    char buffer[SIZE];
13471d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent    String8 result;
13481d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent
13491d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent    snprintf(buffer, SIZE, "\n- %d Effect Chains:\n", mEffectChains.size());
13501d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent    write(fd, buffer, strlen(buffer));
13511d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent
13521d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent    for (size_t i = 0; i < mEffectChains.size(); ++i) {
13531d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent        sp<EffectChain> chain = mEffectChains[i];
13541d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent        if (chain != 0) {
13551d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent            chain->dump(fd, args);
13561d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent        }
13571d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent    }
13581d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent}
13591d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent
1360feb0db689c17dced50afaee54c659f1676e2d505Eric Laurentvoid AudioFlinger::ThreadBase::acquireWakeLock()
1361feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent{
1362feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    Mutex::Autolock _l(mLock);
1363feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    acquireWakeLock_l();
1364feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent}
1365feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
1366feb0db689c17dced50afaee54c659f1676e2d505Eric Laurentvoid AudioFlinger::ThreadBase::acquireWakeLock_l()
1367feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent{
1368feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    if (mPowerManager == 0) {
1369feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        // use checkService() to avoid blocking if power service is not up yet
1370feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        sp<IBinder> binder =
1371feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent            defaultServiceManager()->checkService(String16("power"));
1372feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        if (binder == 0) {
13735ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("Thread %s cannot connect to the power manager service", mName);
1374feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        } else {
1375feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent            mPowerManager = interface_cast<IPowerManager>(binder);
1376feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent            binder->linkToDeath(mDeathRecipient);
1377feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        }
1378feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    }
1379feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    if (mPowerManager != 0) {
1380feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        sp<IBinder> binder = new BBinder();
1381feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        status_t status = mPowerManager->acquireWakeLock(POWERMANAGER_PARTIAL_WAKE_LOCK,
1382feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent                                                         binder,
1383feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent                                                         String16(mName));
1384feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        if (status == NO_ERROR) {
1385feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent            mWakeLockToken = binder;
1386feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        }
13873856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("acquireWakeLock_l() %s status %d", mName, status);
1388feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    }
1389feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent}
1390feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
1391feb0db689c17dced50afaee54c659f1676e2d505Eric Laurentvoid AudioFlinger::ThreadBase::releaseWakeLock()
1392feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent{
1393feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    Mutex::Autolock _l(mLock);
13946dbe883644940badc684957cfc381bfd115f205eEric Laurent    releaseWakeLock_l();
1395feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent}
1396feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
1397feb0db689c17dced50afaee54c659f1676e2d505Eric Laurentvoid AudioFlinger::ThreadBase::releaseWakeLock_l()
1398feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent{
1399feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    if (mWakeLockToken != 0) {
14003856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("releaseWakeLock_l() %s", mName);
1401feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        if (mPowerManager != 0) {
1402feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent            mPowerManager->releaseWakeLock(mWakeLockToken, 0);
1403feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        }
1404feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        mWakeLockToken.clear();
1405feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    }
1406feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent}
1407feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
1408feb0db689c17dced50afaee54c659f1676e2d505Eric Laurentvoid AudioFlinger::ThreadBase::clearPowerManager()
1409feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent{
1410feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    Mutex::Autolock _l(mLock);
1411feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    releaseWakeLock_l();
1412feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    mPowerManager.clear();
1413feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent}
1414feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
1415feb0db689c17dced50afaee54c659f1676e2d505Eric Laurentvoid AudioFlinger::ThreadBase::PMDeathRecipient::binderDied(const wp<IBinder>& who)
1416feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent{
1417feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    sp<ThreadBase> thread = mThread.promote();
1418feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    if (thread != 0) {
1419feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent        thread->clearPowerManager();
1420feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    }
14215ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block    ALOGW("power manager service died !!!");
1422feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent}
14231d2bff0e588afe183a1baaae731519b4e957bbdbEric Laurent
142459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurentvoid AudioFlinger::ThreadBase::setEffectSuspended(
142559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        const effect_uuid_t *type, bool suspend, int sessionId)
142659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent{
142759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    Mutex::Autolock _l(mLock);
142859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    setEffectSuspended_l(type, suspend, sessionId);
142959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent}
143059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
143159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurentvoid AudioFlinger::ThreadBase::setEffectSuspended_l(
143259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        const effect_uuid_t *type, bool suspend, int sessionId)
143359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent{
1434090f01963e215f895020a31e22368cd44e086ce3Glenn Kasten    sp<EffectChain> chain = getEffectChain_l(sessionId);
143559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    if (chain != 0) {
143659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        if (type != NULL) {
143759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            chain->setEffectSuspended_l(type, suspend);
143859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        } else {
143959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            chain->setEffectSuspendedAll_l(suspend);
144059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
144159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
144259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
144359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    updateSuspendedSessions_l(type, suspend, sessionId);
144459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent}
144559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
144659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurentvoid AudioFlinger::ThreadBase::checkSuspendOnAddEffectChain_l(const sp<EffectChain>& chain)
144759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent{
14488d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    ssize_t index = mSuspendedSessions.indexOfKey(chain->sessionId());
144959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    if (index < 0) {
145059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        return;
145159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
145259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
14530a7af18d0308295405491f86603e3d119450aba0Glenn Kasten    const KeyedVector <int, sp<SuspendedSessionDesc> >& sessionEffects =
14540a7af18d0308295405491f86603e3d119450aba0Glenn Kasten            mSuspendedSessions.valueAt(index);
145559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
145659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    for (size_t i = 0; i < sessionEffects.size(); i++) {
1457e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        sp<SuspendedSessionDesc> desc = sessionEffects.valueAt(i);
145859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        for (int j = 0; j < desc->mRefCount; j++) {
145959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            if (sessionEffects.keyAt(i) == EffectChain::kKeyForSuspendAll) {
146059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                chain->setEffectSuspendedAll_l(true);
146159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            } else {
14623856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("checkSuspendOnAddEffectChain_l() suspending effects %08x",
1463e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    desc->mType.timeLow);
146459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                chain->setEffectSuspended_l(&desc->mType, true);
146559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            }
146659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
146759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
146859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent}
146959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
147059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurentvoid AudioFlinger::ThreadBase::updateSuspendedSessions_l(const effect_uuid_t *type,
147159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                                                         bool suspend,
147259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                                                         int sessionId)
147359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent{
14748d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    ssize_t index = mSuspendedSessions.indexOfKey(sessionId);
147559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
147659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    KeyedVector <int, sp<SuspendedSessionDesc> > sessionEffects;
147759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
147859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    if (suspend) {
147959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        if (index >= 0) {
14800a7af18d0308295405491f86603e3d119450aba0Glenn Kasten            sessionEffects = mSuspendedSessions.valueAt(index);
148159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        } else {
148259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            mSuspendedSessions.add(sessionId, sessionEffects);
148359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
148459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    } else {
148559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        if (index < 0) {
148659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            return;
148759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
14880a7af18d0308295405491f86603e3d119450aba0Glenn Kasten        sessionEffects = mSuspendedSessions.valueAt(index);
148959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
149059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
149159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
149259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    int key = EffectChain::kKeyForSuspendAll;
149359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    if (type != NULL) {
149459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        key = type->timeLow;
149559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
149659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    index = sessionEffects.indexOfKey(key);
149759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
1498e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    sp<SuspendedSessionDesc> desc;
149959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    if (suspend) {
150059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        if (index >= 0) {
150159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            desc = sessionEffects.valueAt(index);
150259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        } else {
150359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            desc = new SuspendedSessionDesc();
150459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            if (type != NULL) {
1505a189a6883ee55cf62da1d7bf5bf5a8ab501938a4Glenn Kasten                desc->mType = *type;
150659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            }
150759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            sessionEffects.add(key, desc);
15083856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("updateSuspendedSessions_l() suspend adding effect %08x", key);
150959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
151059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        desc->mRefCount++;
151159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    } else {
151259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        if (index < 0) {
151359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            return;
151459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
151559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        desc = sessionEffects.valueAt(index);
151659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        if (--desc->mRefCount == 0) {
15173856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("updateSuspendedSessions_l() restore removing effect %08x", key);
151859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            sessionEffects.removeItemsAt(index);
151959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            if (sessionEffects.isEmpty()) {
15203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("updateSuspendedSessions_l() restore removing session %d",
152159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                                 sessionId);
152259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                mSuspendedSessions.removeItem(sessionId);
152359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            }
152459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
152559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
152659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    if (!sessionEffects.isEmpty()) {
152759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        mSuspendedSessions.replaceValueFor(sessionId, sessionEffects);
152859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
152959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent}
153059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
153159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurentvoid AudioFlinger::ThreadBase::checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
153259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                                                            bool enabled,
153359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                                                            int sessionId)
153459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent{
153559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    Mutex::Autolock _l(mLock);
1536a85a74a8219c03f2b1d1ef98f3f02e55f89f89a3Eric Laurent    checkSuspendOnEffectEnabled_l(effect, enabled, sessionId);
1537a85a74a8219c03f2b1d1ef98f3f02e55f89f89a3Eric Laurent}
153859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
1539a85a74a8219c03f2b1d1ef98f3f02e55f89f89a3Eric Laurentvoid AudioFlinger::ThreadBase::checkSuspendOnEffectEnabled_l(const sp<EffectModule>& effect,
1540a85a74a8219c03f2b1d1ef98f3f02e55f89f89a3Eric Laurent                                                            bool enabled,
1541a85a74a8219c03f2b1d1ef98f3f02e55f89f89a3Eric Laurent                                                            int sessionId)
1542a85a74a8219c03f2b1d1ef98f3f02e55f89f89a3Eric Laurent{
1543db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent    if (mType != RECORD) {
1544db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent        // suspend all effects in AUDIO_SESSION_OUTPUT_MIX when enabling any effect on
1545db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent        // another session. This gives the priority to well behaved effect control panels
1546db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent        // and applications not using global effects.
1547808e7d16504cbe5b28bb88c31afb2542ab488965Eric Laurent        // Enabling post processing in AUDIO_SESSION_OUTPUT_STAGE session does not affect
1548808e7d16504cbe5b28bb88c31afb2542ab488965Eric Laurent        // global effects
1549808e7d16504cbe5b28bb88c31afb2542ab488965Eric Laurent        if ((sessionId != AUDIO_SESSION_OUTPUT_MIX) && (sessionId != AUDIO_SESSION_OUTPUT_STAGE)) {
1550db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent            setEffectSuspended_l(NULL, enabled, AUDIO_SESSION_OUTPUT_MIX);
1551db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent        }
1552db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent    }
155359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
155459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    sp<EffectChain> chain = getEffectChain_l(sessionId);
155559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    if (chain != 0) {
155659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        chain->checkSuspendOnEffectEnabled(effect, enabled);
155759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
155859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent}
155959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
156065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
156165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
15627c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric LaurentAudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger,
15637c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                             AudioStreamOut* output,
156472ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten                                             audio_io_handle_t id,
1565bb4350d3b9e9485ae59e084de270f86aecef8066Glenn Kasten                                             audio_devices_t device,
156623bb8becff20449a9b1647d5a1a99b14c83f0cceGlenn Kasten                                             type_t type)
1567f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent    :   ThreadBase(audioFlinger, id, device, AUDIO_DEVICE_NONE, type),
156884afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten        mMixBuffer(NULL), mSuspended(0), mBytesWritten(0),
156984afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten        // mStreamTypes[] initialized in constructor body
157084afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten        mOutput(output),
1571fec279f5a0bfaa2a42e91ab6dfa0282baeee308bGlenn Kasten        mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false),
1572aa4397f07c43bd83bc3100b749401dc3d15e7622Glenn Kasten        mMixerStatus(MIXER_IDLE),
1573810280460da5000785662f6c5b0c7ff3ee0a4cb3Glenn Kasten        mMixerStatusIgnoringFastTracks(MIXER_IDLE),
157458912562617941964939a4182cda71eaeb153d4bGlenn Kasten        standbyDelay(AudioFlinger::mStandbyTimeInNsecs),
157528ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten        mScreenState(gScreenState),
1576288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        // index 0 is reserved for normal mixer's submix
1577288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        mFastTrackAvailMask(((1 << FastMixerState::kMaxFastTracks) - 1) & ~1)
157865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
1579480b46802bef1371d5caa16ad5454fce04769c57Glenn Kasten    snprintf(mName, kNameLength, "AudioOut_%X", id);
1580feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
1581ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // Assumes constructor is called by AudioFlinger with it's mLock held, but
1582ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // it would be safer to explicitly pass initial masterVolume/masterMute as
1583ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // parameter.
1584ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    //
1585ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // If the HAL we are using has support for master volume or master mute,
1586ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // then do not attenuate or mute during mixing (just leave the volume at 1.0
1587ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // and the mute set to false).
1588ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    mMasterVolume = audioFlinger->masterVolume_l();
1589ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    mMasterMute = audioFlinger->masterMute_l();
1590ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    if (mOutput && mOutput->audioHwDev) {
1591ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        if (mOutput->audioHwDev->canSetMasterVolume()) {
1592ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman            mMasterVolume = 1.0;
1593ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        }
1594ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman
1595ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        if (mOutput->audioHwDev->canSetMasterMute()) {
1596ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman            mMasterMute = false;
1597ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        }
1598ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    }
1599ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman
160065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    readOutputParameters();
160165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1602263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    // mStreamTypes[AUDIO_STREAM_CNT] is initialized by stream_type_t default constructor
1603fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten    // There is no AUDIO_STREAM_MIN, and ++ operator does not compile
1604fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten    for (audio_stream_type_t stream = (audio_stream_type_t) 0; stream < AUDIO_STREAM_CNT;
1605fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten            stream = (audio_stream_type_t) (stream + 1)) {
16066637baae4244aec731c4014da72418d330636ae1Glenn Kasten        mStreamTypes[stream].volume = mAudioFlinger->streamVolume_l(stream);
16076637baae4244aec731c4014da72418d330636ae1Glenn Kasten        mStreamTypes[stream].mute = mAudioFlinger->streamMute_l(stream);
160865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
16096637baae4244aec731c4014da72418d330636ae1Glenn Kasten    // mStreamTypes[AUDIO_STREAM_CNT] exists but isn't explicitly initialized here,
16106637baae4244aec731c4014da72418d330636ae1Glenn Kasten    // because mAudioFlinger doesn't have one to copy from
161165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
161265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
161365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::PlaybackThread::~PlaybackThread()
161465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
161565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    delete [] mMixBuffer;
161665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
161765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1618be5f05e0fdfc4e3799653702187861a2afa072eeGlenn Kastenvoid AudioFlinger::PlaybackThread::dump(int fd, const Vector<String16>& args)
161965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
162065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    dumpInternals(fd, args);
162165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    dumpTracks(fd, args);
162265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    dumpEffectChains(fd, args);
162365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
162465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1625be5f05e0fdfc4e3799653702187861a2afa072eeGlenn Kastenvoid AudioFlinger::PlaybackThread::dumpTracks(int fd, const Vector<String16>& args)
162665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
162765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
162865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
162965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
163065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
163158912562617941964939a4182cda71eaeb153d4bGlenn Kasten    result.appendFormat("Output thread %p stream volumes in dB:\n    ", this);
163258912562617941964939a4182cda71eaeb153d4bGlenn Kasten    for (int i = 0; i < AUDIO_STREAM_CNT; ++i) {
163358912562617941964939a4182cda71eaeb153d4bGlenn Kasten        const stream_type_t *st = &mStreamTypes[i];
163458912562617941964939a4182cda71eaeb153d4bGlenn Kasten        if (i > 0) {
163558912562617941964939a4182cda71eaeb153d4bGlenn Kasten            result.appendFormat(", ");
163658912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
163758912562617941964939a4182cda71eaeb153d4bGlenn Kasten        result.appendFormat("%d:%.2g", i, 20.0 * log10(st->volume));
163858912562617941964939a4182cda71eaeb153d4bGlenn Kasten        if (st->mute) {
163958912562617941964939a4182cda71eaeb153d4bGlenn Kasten            result.append("M");
164058912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
164158912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
164258912562617941964939a4182cda71eaeb153d4bGlenn Kasten    result.append("\n");
164358912562617941964939a4182cda71eaeb153d4bGlenn Kasten    write(fd, result.string(), result.length());
164458912562617941964939a4182cda71eaeb153d4bGlenn Kasten    result.clear();
164558912562617941964939a4182cda71eaeb153d4bGlenn Kasten
164665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "Output thread %p tracks\n", this);
164765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
1648288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    Track::appendDumpHeader(result);
164965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < mTracks.size(); ++i) {
165065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<Track> track = mTracks[i];
165165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (track != 0) {
165265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            track->dump(buffer, SIZE);
165365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            result.append(buffer);
165465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
165565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
165665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
165765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "Output thread %p active tracks\n", this);
165865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
1659288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    Track::appendDumpHeader(result);
166065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < mActiveTracks.size(); ++i) {
166177c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten        sp<Track> track = mActiveTracks[i].promote();
166277c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten        if (track != 0) {
166377c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten            track->dump(buffer, SIZE);
166477c1119ea0b5cb32287088ceeeb7e3b6bd14a85dGlenn Kasten            result.append(buffer);
166565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
166665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
166765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
166888cbea8a918bbaf5e06e48aadd5af5e81d58d232Glenn Kasten
166988cbea8a918bbaf5e06e48aadd5af5e81d58d232Glenn Kasten    // These values are "raw"; they will wrap around.  See prepareTracks_l() for a better way.
167088cbea8a918bbaf5e06e48aadd5af5e81d58d232Glenn Kasten    FastTrackUnderruns underruns = getFastTrackUnderruns(0);
167188cbea8a918bbaf5e06e48aadd5af5e81d58d232Glenn Kasten    fdprintf(fd, "Normal mixer raw underrun counters: partial=%u empty=%u\n",
167288cbea8a918bbaf5e06e48aadd5af5e81d58d232Glenn Kasten            underruns.mBitFields.mPartial, underruns.mBitFields.mEmpty);
167365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
167465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1675be5f05e0fdfc4e3799653702187861a2afa072eeGlenn Kastenvoid AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String16>& args)
167665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
167765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
167865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
167965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
168065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
168165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "\nOutput thread %p internals\n", this);
168265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
168385ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten    snprintf(buffer, SIZE, "last write occurred (msecs): %llu\n",
168485ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten            ns2ms(systemTime() - mLastWriteTime));
168565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
168665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "total writes: %d\n", mNumWrites);
168765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
168865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "delayed writes: %d\n", mNumDelayedWrites);
168965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
169065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "blocked in write: %d\n", mInWrite);
169165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
169265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "suspend count: %d\n", mSuspended);
169365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
169465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "mix buffer : %p\n", mMixBuffer);
169565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
169665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
16971295bb4dcff7b29c75cd23746816df12a871d72cGlenn Kasten    fdprintf(fd, "Fast track availMask=%#x\n", mFastTrackAvailMask);
169865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
169965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    dumpBase(fd, args);
170065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
170165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
170265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Thread virtuals
170365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::PlaybackThread::readyToRun()
170465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
1705b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    status_t status = initCheck();
1706b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    if (status == NO_ERROR) {
1707df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block        ALOGI("AudioFlinger's thread %p ready to run", this);
1708b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    } else {
170929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("No working audio driver found.");
171065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
1711b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    return status;
171265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
171365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
171465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::PlaybackThread::onFirstRef()
171565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
1716feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    run(mName, ANDROID_PRIORITY_URGENT_AUDIO);
171765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
171865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
17192bfc6b42b3733c12485dd51ed95191956abc3e4eJean-Michel Trivi// ThreadBase virtuals
17202bfc6b42b3733c12485dd51ed95191956abc3e4eJean-Michel Trivivoid AudioFlinger::PlaybackThread::preExit()
17212bfc6b42b3733c12485dd51ed95191956abc3e4eJean-Michel Trivi{
17222bfc6b42b3733c12485dd51ed95191956abc3e4eJean-Michel Trivi    ALOGV("  preExit()");
17232bfc6b42b3733c12485dd51ed95191956abc3e4eJean-Michel Trivi    // FIXME this is using hard-coded strings but in the future, this functionality will be
17242bfc6b42b3733c12485dd51ed95191956abc3e4eJean-Michel Trivi    //       converted to use audio HAL extensions required to support tunneling
17252bfc6b42b3733c12485dd51ed95191956abc3e4eJean-Michel Trivi    mOutput->stream->common.set_parameters(&mOutput->stream->common, "exiting=1");
17262bfc6b42b3733c12485dd51ed95191956abc3e4eJean-Michel Trivi}
17272bfc6b42b3733c12485dd51ed95191956abc3e4eJean-Michel Trivi
172865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// PlaybackThread::createTrack_l() must be called with AudioFlinger::mLock held
1729ea7939a079b3600cab955760839b021326f8cfc3Glenn Kastensp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrack_l(
173065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        const sp<AudioFlinger::Client>& client,
1731fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten        audio_stream_type_t streamType,
173265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        uint32_t sampleRate,
173358f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten        audio_format_t format,
1734254af180475346b6186b49c297f340c9c4817511Glenn Kasten        audio_channel_mask_t channelMask,
1735e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten        size_t frameCount,
173665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        const sp<IMemory>& sharedBuffer,
173765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int sessionId,
1738e0b07179a48ee50fda931d2aa1b3c751d167e4d7Glenn Kasten        IAudioFlinger::track_flags_t *flags,
17393acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten        pid_t tid,
174065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status_t *status)
174165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
174265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<Track> track;
174365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t lStatus;
174465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1745e0b07179a48ee50fda931d2aa1b3c751d167e4d7Glenn Kasten    bool isTimed = (*flags & IAudioFlinger::TRACK_TIMED) != 0;
174673d227557ba5192735356bacab9f77b44980793bGlenn Kasten
174773d227557ba5192735356bacab9f77b44980793bGlenn Kasten    // client expresses a preference for FAST, but we get the final say
1748e0b07179a48ee50fda931d2aa1b3c751d167e4d7Glenn Kasten    if (*flags & IAudioFlinger::TRACK_FAST) {
1749e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten      if (
175073d227557ba5192735356bacab9f77b44980793bGlenn Kasten            // not timed
175173d227557ba5192735356bacab9f77b44980793bGlenn Kasten            (!isTimed) &&
175273d227557ba5192735356bacab9f77b44980793bGlenn Kasten            // either of these use cases:
175373d227557ba5192735356bacab9f77b44980793bGlenn Kasten            (
175473d227557ba5192735356bacab9f77b44980793bGlenn Kasten              // use case 1: shared buffer with any frame count
175573d227557ba5192735356bacab9f77b44980793bGlenn Kasten              (
175673d227557ba5192735356bacab9f77b44980793bGlenn Kasten                (sharedBuffer != 0)
175773d227557ba5192735356bacab9f77b44980793bGlenn Kasten              ) ||
1758e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten              // use case 2: callback handler and frame count is default or at least as large as HAL
175973d227557ba5192735356bacab9f77b44980793bGlenn Kasten              (
17603acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten                (tid != -1) &&
1761e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten                ((frameCount == 0) ||
17623ed292031dc50c56110cdadb1e3778117e3be76aGlenn Kasten                (frameCount >= (int) (mFrameCount * kFastTrackMultiplier)))
176373d227557ba5192735356bacab9f77b44980793bGlenn Kasten              )
176473d227557ba5192735356bacab9f77b44980793bGlenn Kasten            ) &&
176573d227557ba5192735356bacab9f77b44980793bGlenn Kasten            // PCM data
176673d227557ba5192735356bacab9f77b44980793bGlenn Kasten            audio_is_linear_pcm(format) &&
176773d227557ba5192735356bacab9f77b44980793bGlenn Kasten            // mono or stereo
176873d227557ba5192735356bacab9f77b44980793bGlenn Kasten            ( (channelMask == AUDIO_CHANNEL_OUT_MONO) ||
176973d227557ba5192735356bacab9f77b44980793bGlenn Kasten              (channelMask == AUDIO_CHANNEL_OUT_STEREO) ) &&
177058912562617941964939a4182cda71eaeb153d4bGlenn Kasten#ifndef FAST_TRACKS_AT_NON_NATIVE_SAMPLE_RATE
177173d227557ba5192735356bacab9f77b44980793bGlenn Kasten            // hardware sample rate
177258912562617941964939a4182cda71eaeb153d4bGlenn Kasten            (sampleRate == mSampleRate) &&
177358912562617941964939a4182cda71eaeb153d4bGlenn Kasten#endif
177458912562617941964939a4182cda71eaeb153d4bGlenn Kasten            // normal mixer has an associated fast mixer
177558912562617941964939a4182cda71eaeb153d4bGlenn Kasten            hasFastMixer() &&
177658912562617941964939a4182cda71eaeb153d4bGlenn Kasten            // there are sufficient fast track slots available
177758912562617941964939a4182cda71eaeb153d4bGlenn Kasten            (mFastTrackAvailMask != 0)
177873d227557ba5192735356bacab9f77b44980793bGlenn Kasten            // FIXME test that MixerThread for this fast track has a capable output HAL
177973d227557ba5192735356bacab9f77b44980793bGlenn Kasten            // FIXME add a permission test also?
1780e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten        ) {
1781e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten        // if frameCount not specified, then it defaults to fast mixer (HAL) frame count
1782e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten        if (frameCount == 0) {
17833ed292031dc50c56110cdadb1e3778117e3be76aGlenn Kasten            frameCount = mFrameCount * kFastTrackMultiplier;
1784e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten        }
178531dfd1db7a4d2228d9642008af6f3dd744368eb6Glenn Kasten        ALOGV("AUDIO_OUTPUT_FLAG_FAST accepted: frameCount=%d mFrameCount=%d",
1786300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten                frameCount, mFrameCount);
1787e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten      } else {
1788852fca99e25db8d2180c2622ca55fca676490a08Glenn Kasten        ALOGV("AUDIO_OUTPUT_FLAG_FAST denied: isTimed=%d sharedBuffer=%p frameCount=%d "
17893b16c766d1ae2cfd8487e8ffb2b23936fc0a8e17Glenn Kasten                "mFrameCount=%d format=%d isLinear=%d channelMask=%#x sampleRate=%u mSampleRate=%u "
179058912562617941964939a4182cda71eaeb153d4bGlenn Kasten                "hasFastMixer=%d tid=%d fastTrackAvailMask=%#x",
179158912562617941964939a4182cda71eaeb153d4bGlenn Kasten                isTimed, sharedBuffer.get(), frameCount, mFrameCount, format,
179258912562617941964939a4182cda71eaeb153d4bGlenn Kasten                audio_is_linear_pcm(format),
179358912562617941964939a4182cda71eaeb153d4bGlenn Kasten                channelMask, sampleRate, mSampleRate, hasFastMixer(), tid, mFastTrackAvailMask);
1794e0b07179a48ee50fda931d2aa1b3c751d167e4d7Glenn Kasten        *flags &= ~IAudioFlinger::TRACK_FAST;
1795e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten        // For compatibility with AudioTrack calculation, buffer depth is forced
1796e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten        // to be at least 2 x the normal mixer frame count and cover audio hardware latency.
1797e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten        // This is probably too conservative, but legacy application code may depend on it.
1798e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten        // If you change this calculation, also review the start threshold which is related.
1799e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten        uint32_t latencyMs = mOutput->stream->get_latency(mOutput->stream);
1800e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten        uint32_t minBufCount = latencyMs / ((1000 * mNormalFrameCount) / mSampleRate);
1801e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten        if (minBufCount < 2) {
1802e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten            minBufCount = 2;
1803e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten        }
1804e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten        size_t minFrameCount = mNormalFrameCount * minBufCount;
1805e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten        if (frameCount < minFrameCount) {
1806e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten            frameCount = minFrameCount;
180758912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
1808e0fa467e1150c65a7b1b1ed904c579b40f97c9dfGlenn Kasten      }
180973d227557ba5192735356bacab9f77b44980793bGlenn Kasten    }
181073d227557ba5192735356bacab9f77b44980793bGlenn Kasten
181165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mType == DIRECT) {
18120d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi        if ((format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_PCM) {
18130d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi            if (sampleRate != mSampleRate || format != mFormat || channelMask != mChannelMask) {
18143b16c766d1ae2cfd8487e8ffb2b23936fc0a8e17Glenn Kasten                ALOGE("createTrack_l() Bad parameter: sampleRate %u format %d, channelMask 0x%08x "
18150d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi                        "for output %p with format %d",
18160d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi                        sampleRate, format, channelMask, mOutput, mFormat);
18170d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi                lStatus = BAD_VALUE;
18180d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi                goto Exit;
18190d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi            }
182065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
182165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
182265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Resampler implementation limits input sampling rate to 2 x output sampling rate.
182365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (sampleRate > mSampleRate*2) {
18243b16c766d1ae2cfd8487e8ffb2b23936fc0a8e17Glenn Kasten            ALOGE("Sample rate out of range: %u mSampleRate %u", sampleRate, mSampleRate);
182565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            lStatus = BAD_VALUE;
182665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            goto Exit;
182765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
182865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
182965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
18307c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    lStatus = initCheck();
18317c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (lStatus != NO_ERROR) {
183229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Audio driver not initialized.");
183365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        goto Exit;
183465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
183565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
183665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    { // scope for mLock
183765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock _l(mLock);
1838de070137f11d346fba77605bd76a44c040a618fcEric Laurent
1839de070137f11d346fba77605bd76a44c040a618fcEric Laurent        // all tracks in same audio session must share the same routing strategy otherwise
1840de070137f11d346fba77605bd76a44c040a618fcEric Laurent        // conflicts will happen when tracks are moved from one output to another by audio policy
1841de070137f11d346fba77605bd76a44c040a618fcEric Laurent        // manager
184202bbd20cece1785c223ac4ca2ddc635931a80673Glenn Kasten        uint32_t strategy = AudioSystem::getStrategyForStream(streamType);
1843de070137f11d346fba77605bd76a44c040a618fcEric Laurent        for (size_t i = 0; i < mTracks.size(); ++i) {
1844de070137f11d346fba77605bd76a44c040a618fcEric Laurent            sp<Track> t = mTracks[i];
1845639dbee79140956c43926344c23af765f6e0c9a5Glenn Kasten            if (t != 0 && !t->isOutputTrack()) {
184602bbd20cece1785c223ac4ca2ddc635931a80673Glenn Kasten                uint32_t actual = AudioSystem::getStrategyForStream(t->streamType());
1847d879601ace079e3c0aed79cf3fa5fb4db6ad4a9fGlenn Kasten                if (sessionId == t->sessionId() && strategy != actual) {
184829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("createTrack_l() mismatched strategy; expected %u but found %u",
1849d879601ace079e3c0aed79cf3fa5fb4db6ad4a9fGlenn Kasten                            strategy, actual);
1850de070137f11d346fba77605bd76a44c040a618fcEric Laurent                    lStatus = BAD_VALUE;
1851de070137f11d346fba77605bd76a44c040a618fcEric Laurent                    goto Exit;
1852de070137f11d346fba77605bd76a44c040a618fcEric Laurent                }
1853de070137f11d346fba77605bd76a44c040a618fcEric Laurent            }
1854de070137f11d346fba77605bd76a44c040a618fcEric Laurent        }
1855de070137f11d346fba77605bd76a44c040a618fcEric Laurent
18564ff14bae91075eb274eb1c2975982358946e7e63John Grossman        if (!isTimed) {
18574ff14bae91075eb274eb1c2975982358946e7e63John Grossman            track = new Track(this, client, streamType, sampleRate, format,
1858e0b07179a48ee50fda931d2aa1b3c751d167e4d7Glenn Kasten                    channelMask, frameCount, sharedBuffer, sessionId, *flags);
18594ff14bae91075eb274eb1c2975982358946e7e63John Grossman        } else {
18604ff14bae91075eb274eb1c2975982358946e7e63John Grossman            track = TimedTrack::create(this, client, streamType, sampleRate, format,
18614ff14bae91075eb274eb1c2975982358946e7e63John Grossman                    channelMask, frameCount, sharedBuffer, sessionId);
18624ff14bae91075eb274eb1c2975982358946e7e63John Grossman        }
1863d5903ec1332630f2992a6f0d5ca69d13a185c665Glenn Kasten        if (track == 0 || track->getCblk() == NULL || track->name() < 0) {
186465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            lStatus = NO_MEMORY;
186565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            goto Exit;
186665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
186765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mTracks.add(track);
186865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
186965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<EffectChain> chain = getEffectChain_l(sessionId);
187065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (chain != 0) {
18713856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("createTrack_l() setting main buffer %p", chain->inBuffer());
187265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            track->setMainBuffer(chain->inBuffer());
187302bbd20cece1785c223ac4ca2ddc635931a80673Glenn Kasten            chain->setStrategy(AudioSystem::getStrategyForStream(track->streamType()));
1874b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent            chain->incTrackCnt();
187565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
18763acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten
1877e0b07179a48ee50fda931d2aa1b3c751d167e4d7Glenn Kasten        if ((*flags & IAudioFlinger::TRACK_FAST) && (tid != -1)) {
1878896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent            pid_t callingPid = IPCThreadState::self()->getCallingPid();
1879896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent            // we don't have CAP_SYS_NICE, nor do we want to have it as it's too powerful,
1880896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent            // so ask activity manager to do this on our behalf
1881896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent            sendPrioConfigEvent_l(callingPid, tid, kPriorityAudioApp);
18823acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten        }
18833acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten    }
18843acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten
188565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    lStatus = NO_ERROR;
188665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
188765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianExit:
1888e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    if (status) {
188965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        *status = lStatus;
189065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
189165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return track;
189265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
189365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1894e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurentuint32_t AudioFlinger::MixerThread::correctLatency(uint32_t latency) const
1895e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent{
1896e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent    if (mFastMixer != NULL) {
1897e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent        MonoPipe *pipe = (MonoPipe *)mPipeSink.get();
1898e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent        latency += (pipe->getAvgFrames() * 1000) / mSampleRate;
1899e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent    }
1900e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent    return latency;
1901e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent}
1902e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent
1903e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurentuint32_t AudioFlinger::PlaybackThread::correctLatency(uint32_t latency) const
1904e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent{
1905e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent    return latency;
1906e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent}
1907e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent
190865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianuint32_t AudioFlinger::PlaybackThread::latency() const
190965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
1910b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    Mutex::Autolock _l(mLock);
1911f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissen    return latency_l();
1912f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissen}
1913f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissenuint32_t AudioFlinger::PlaybackThread::latency_l() const
1914f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissen{
1915b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    if (initCheck() == NO_ERROR) {
1916e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent        return correctLatency(mOutput->stream->get_latency(mOutput->stream));
1917b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    } else {
191865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return 0;
191965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
192065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
192165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
19226637baae4244aec731c4014da72418d330636ae1Glenn Kastenvoid AudioFlinger::PlaybackThread::setMasterVolume(float value)
192365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
19246637baae4244aec731c4014da72418d330636ae1Glenn Kasten    Mutex::Autolock _l(mLock);
1925ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // Don't apply master volume in SW if our HAL can do it for us.
1926ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    if (mOutput && mOutput->audioHwDev &&
1927ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mOutput->audioHwDev->canSetMasterVolume()) {
1928ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mMasterVolume = 1.0;
1929ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    } else {
1930ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mMasterVolume = value;
1931ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    }
193265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
193365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
19346637baae4244aec731c4014da72418d330636ae1Glenn Kastenvoid AudioFlinger::PlaybackThread::setMasterMute(bool muted)
193565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
19366637baae4244aec731c4014da72418d330636ae1Glenn Kasten    Mutex::Autolock _l(mLock);
1937ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // Don't apply master mute in SW if our HAL can do it for us.
1938ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    if (mOutput && mOutput->audioHwDev &&
1939ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mOutput->audioHwDev->canSetMasterMute()) {
1940ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mMasterMute = false;
1941ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    } else {
1942ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mMasterMute = muted;
1943ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    }
194465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
194565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
19466637baae4244aec731c4014da72418d330636ae1Glenn Kastenvoid AudioFlinger::PlaybackThread::setStreamVolume(audio_stream_type_t stream, float value)
194765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
19486637baae4244aec731c4014da72418d330636ae1Glenn Kasten    Mutex::Autolock _l(mLock);
194965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mStreamTypes[stream].volume = value;
195065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
195165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
19526637baae4244aec731c4014da72418d330636ae1Glenn Kastenvoid AudioFlinger::PlaybackThread::setStreamMute(audio_stream_type_t stream, bool muted)
195365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
19546637baae4244aec731c4014da72418d330636ae1Glenn Kasten    Mutex::Autolock _l(mLock);
195565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mStreamTypes[stream].mute = muted;
195665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
195765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1958fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kastenfloat AudioFlinger::PlaybackThread::streamVolume(audio_stream_type_t stream) const
195965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
19606637baae4244aec731c4014da72418d330636ae1Glenn Kasten    Mutex::Autolock _l(mLock);
196165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mStreamTypes[stream].volume;
196265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
196365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
196465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// addTrack_l() must be called with ThreadBase::mLock held
196565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::PlaybackThread::addTrack_l(const sp<Track>& track)
196665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
196765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t status = ALREADY_EXISTS;
196865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
196965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // set retry count for buffer fill
197065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    track->mRetryCount = kMaxTrackStartupRetries;
197165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mActiveTracks.indexOf(track) < 0) {
197265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // the track is newly added, make sure it fills up all its
197365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // buffers before playing. This is to ensure the client will
197465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // effectively get the latency it requested.
197565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        track->mFillingUpStatus = Track::FS_FILLING;
197665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        track->mResetDone = false;
19772986460984580833161bdaabc7f17da1005a8961Eric Laurent        track->mPresentationCompleteFrames = 0;
197865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mActiveTracks.add(track);
197965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (track->mainBuffer() != mMixBuffer) {
198065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            sp<EffectChain> chain = getEffectChain_l(track->sessionId());
198165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (chain != 0) {
198285ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                ALOGV("addTrack_l() starting track on chain %p for session %d", chain.get(),
198385ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                        track->sessionId());
1984b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent                chain->incActiveTrackCnt();
198565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
198665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
198765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
198865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status = NO_ERROR;
198965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
199065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
19913856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("mWaitWorkCV.broadcast");
199265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mWaitWorkCV.broadcast();
199365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
199465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return status;
199565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
199665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
199765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// destroyTrack_l() must be called with ThreadBase::mLock held
199865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::PlaybackThread::destroyTrack_l(const sp<Track>& track)
199965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
200065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    track->mState = TrackBase::TERMINATED;
2001288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    // active tracks are removed by threadLoop()
200265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mActiveTracks.indexOf(track) < 0) {
2003b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent        removeTrack_l(track);
2004b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent    }
2005b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent}
2006b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent
2007b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurentvoid AudioFlinger::PlaybackThread::removeTrack_l(const sp<Track>& track)
2008b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent{
20092986460984580833161bdaabc7f17da1005a8961Eric Laurent    track->triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE);
2010b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent    mTracks.remove(track);
2011b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent    deleteTrackName_l(track->name());
2012288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    // redundant as track is about to be destroyed, for dumpsys only
2013288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    track->mName = -1;
2014288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    if (track->isFastTrack()) {
2015288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        int index = track->mFastIndex;
20162986460984580833161bdaabc7f17da1005a8961Eric Laurent        ALOG_ASSERT(0 < index && index < (int)FastMixerState::kMaxFastTracks);
2017288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        ALOG_ASSERT(!(mFastTrackAvailMask & (1 << index)));
2018288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        mFastTrackAvailMask |= 1 << index;
2019288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        // redundant as track is about to be destroyed, for dumpsys only
2020288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        track->mFastIndex = -1;
2021288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    }
2022b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent    sp<EffectChain> chain = getEffectChain_l(track->sessionId());
2023b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent    if (chain != 0) {
2024b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent        chain->decTrackCnt();
202565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
202665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
202765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
202865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianString8 AudioFlinger::PlaybackThread::getParameters(const String8& keys)
202965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
2030b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    String8 out_s8 = String8("");
2031fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    char *s;
2032fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
2033b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    Mutex::Autolock _l(mLock);
2034b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    if (initCheck() != NO_ERROR) {
2035b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent        return out_s8;
2036b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    }
2037b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
2038799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    s = mOutput->stream->common.get_parameters(&mOutput->stream->common, keys.string());
2039fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    out_s8 = String8(s);
2040fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    free(s);
2041fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return out_s8;
204265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
204365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2044b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent// audioConfigChanged_l() must be called with AudioFlinger::mLock held
204565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::PlaybackThread::audioConfigChanged_l(int event, int param) {
204665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    AudioSystem::OutputDescriptor desc;
2047a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten    void *param2 = NULL;
204865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
204985ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten    ALOGV("PlaybackThread::audioConfigChanged_l, thread %p, event %d, param %d", this, event,
205085ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten            param);
205165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
205265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    switch (event) {
205365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    case AudioSystem::OUTPUT_OPENED:
205465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    case AudioSystem::OUTPUT_CONFIG_CHANGED:
20550d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi        desc.channels = mChannelMask;
205665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        desc.samplingRate = mSampleRate;
205765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        desc.format = mFormat;
205885ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten        desc.frameCount = mNormalFrameCount; // FIXME see
205985ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                                             // AudioFlinger::frameCount(audio_io_handle_t)
206065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        desc.latency = latency();
206165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        param2 = &desc;
206265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        break;
206365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
206465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    case AudioSystem::STREAM_CONFIG_CHANGED:
206565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        param2 = &param;
206665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    case AudioSystem::OUTPUT_CLOSED:
206765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    default:
206865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        break;
206965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
207065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mAudioFlinger->audioConfigChanged_l(event, mId, param2);
207165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
207265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
207365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::PlaybackThread::readOutputParameters()
207465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
2075799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    mSampleRate = mOutput->stream->common.get_sample_rate(&mOutput->stream->common);
20760d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi    mChannelMask = mOutput->stream->common.get_channels(&mOutput->stream->common);
20770d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi    mChannelCount = (uint16_t)popcount(mChannelMask);
2078799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    mFormat = mOutput->stream->common.get_format(&mOutput->stream->common);
2079b9980659501d0428d65d8292f3c32da69d37fbd2Glenn Kasten    mFrameSize = audio_stream_frame_size(&mOutput->stream->common);
2080799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    mFrameCount = mOutput->stream->common.get_buffer_size(&mOutput->stream->common) / mFrameSize;
208158912562617941964939a4182cda71eaeb153d4bGlenn Kasten    if (mFrameCount & 15) {
208258912562617941964939a4182cda71eaeb153d4bGlenn Kasten        ALOGW("HAL output buffer size is %u frames but AudioMixer requires multiples of 16 frames",
208358912562617941964939a4182cda71eaeb153d4bGlenn Kasten                mFrameCount);
208458912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
208558912562617941964939a4182cda71eaeb153d4bGlenn Kasten
2086300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    // Calculate size of normal mix buffer relative to the HAL output buffer size
20874adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten    double multiplier = 1.0;
208885ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten    if (mType == MIXER && (kUseFastMixer == FastMixer_Static ||
208985ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten            kUseFastMixer == FastMixer_Dynamic)) {
209058912562617941964939a4182cda71eaeb153d4bGlenn Kasten        size_t minNormalFrameCount = (kMinNormalMixBufferSizeMs * mSampleRate) / 1000;
20914adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten        size_t maxNormalFrameCount = (kMaxNormalMixBufferSizeMs * mSampleRate) / 1000;
20924adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten        // round up minimum and round down maximum to nearest 16 frames to satisfy AudioMixer
20934adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten        minNormalFrameCount = (minNormalFrameCount + 15) & ~15;
20944adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten        maxNormalFrameCount = maxNormalFrameCount & ~15;
20954adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten        if (maxNormalFrameCount < minNormalFrameCount) {
20964adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten            maxNormalFrameCount = minNormalFrameCount;
20974adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten        }
20984adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten        multiplier = (double) minNormalFrameCount / (double) mFrameCount;
20994adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten        if (multiplier <= 1.0) {
21004adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten            multiplier = 1.0;
21014adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten        } else if (multiplier <= 2.0) {
21024adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten            if (2 * mFrameCount <= maxNormalFrameCount) {
21034adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten                multiplier = 2.0;
21044adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten            } else {
21054adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten                multiplier = (double) maxNormalFrameCount / (double) mFrameCount;
21064adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten            }
21074adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten        } else {
210885ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten            // prefer an even multiplier, for compatibility with doubling of fast tracks due to HAL
210985ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten            // SRC (it would be unusual for the normal mix buffer size to not be a multiple of fast
211085ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten            // track, but we sometimes have to do this to satisfy the maximum frame count
211185ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten            // constraint)
21124adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten            // FIXME this rounding up should not be done if no HAL SRC
21134adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten            uint32_t truncMult = (uint32_t) multiplier;
21144adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten            if ((truncMult & 1)) {
21154adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten                if ((truncMult + 1) * mFrameCount <= maxNormalFrameCount) {
21164adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten                    ++truncMult;
21174adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten                }
21184adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten            }
21194adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten            multiplier = (double) truncMult;
212058912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
212158912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
21224adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten    mNormalFrameCount = multiplier * mFrameCount;
21234adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten    // round up to nearest 16 frames to satisfy AudioMixer
21244adcede0dc54a85c31abaf139921aebd7a072d8eGlenn Kasten    mNormalFrameCount = (mNormalFrameCount + 15) & ~15;
212585ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten    ALOGI("HAL output buffer size %u frames, normal mix buffer size %u frames", mFrameCount,
212685ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten            mNormalFrameCount);
212765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2128e9dd0176933d6233916c84e18f3e8c0d644ca05dGlenn Kasten    delete[] mMixBuffer;
212967c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent    mMixBuffer = new int16_t[mNormalFrameCount * mChannelCount];
213067c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent    memset(mMixBuffer, 0, mNormalFrameCount * mChannelCount * sizeof(int16_t));
213165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2132de070137f11d346fba77605bd76a44c040a618fcEric Laurent    // force reconfiguration of effect chains and engines to take new buffer size and audio
2133de070137f11d346fba77605bd76a44c040a618fcEric Laurent    // parameters into account
2134de070137f11d346fba77605bd76a44c040a618fcEric Laurent    // Note that mLock is not held when readOutputParameters() is called from the constructor
2135de070137f11d346fba77605bd76a44c040a618fcEric Laurent    // but in this case nothing is done below as no audio sessions have effect yet so it doesn't
2136de070137f11d346fba77605bd76a44c040a618fcEric Laurent    // matter.
2137de070137f11d346fba77605bd76a44c040a618fcEric Laurent    // create a copy of mEffectChains as calling moveEffectChain_l() can reorder some effect chains
2138de070137f11d346fba77605bd76a44c040a618fcEric Laurent    Vector< sp<EffectChain> > effectChains = mEffectChains;
2139de070137f11d346fba77605bd76a44c040a618fcEric Laurent    for (size_t i = 0; i < effectChains.size(); i ++) {
214039e94f8f723d445447fdee0822291e664b631f60Eric Laurent        mAudioFlinger->moveEffectChain_l(effectChains[i]->sessionId(), this, this, false);
2141de070137f11d346fba77605bd76a44c040a618fcEric Laurent    }
214265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
214365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2144e737cda649acbfa43fc1b74612a83f2fac9aa449Eric Laurent
214565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::PlaybackThread::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames)
214665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
2147a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten    if (halFrames == NULL || dspFrames == NULL) {
214865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return BAD_VALUE;
214965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
2150b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    Mutex::Autolock _l(mLock);
21517c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (initCheck() != NO_ERROR) {
215265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return INVALID_OPERATION;
215365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
2154799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    *halFrames = mBytesWritten / audio_stream_frame_size(&mOutput->stream->common);
215565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
21561afc26db11b71c43f63a0f72a45a803f1a7910ddEric Laurent    if (isSuspended()) {
21571afc26db11b71c43f63a0f72a45a803f1a7910ddEric Laurent        // return an estimation of rendered frames when the output is suspended
21581afc26db11b71c43f63a0f72a45a803f1a7910ddEric Laurent        int32_t frames = mBytesWritten - latency_l();
21591afc26db11b71c43f63a0f72a45a803f1a7910ddEric Laurent        if (frames < 0) {
21601afc26db11b71c43f63a0f72a45a803f1a7910ddEric Laurent            frames = 0;
21611afc26db11b71c43f63a0f72a45a803f1a7910ddEric Laurent        }
21621afc26db11b71c43f63a0f72a45a803f1a7910ddEric Laurent        *dspFrames = (uint32_t)frames;
21631afc26db11b71c43f63a0f72a45a803f1a7910ddEric Laurent        return NO_ERROR;
21641afc26db11b71c43f63a0f72a45a803f1a7910ddEric Laurent    } else {
21651afc26db11b71c43f63a0f72a45a803f1a7910ddEric Laurent        return mOutput->stream->get_render_position(mOutput->stream, dspFrames);
21661afc26db11b71c43f63a0f72a45a803f1a7910ddEric Laurent    }
216765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
216865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2169106e8a42038f9e90d5ff97f8ab6f1a42258bde9eGlenn Kastenuint32_t AudioFlinger::PlaybackThread::hasAudioSession(int sessionId) const
217065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
217165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
217239e94f8f723d445447fdee0822291e664b631f60Eric Laurent    uint32_t result = 0;
217365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (getEffectChain_l(sessionId) != 0) {
217439e94f8f723d445447fdee0822291e664b631f60Eric Laurent        result = EFFECT_SESSION;
217565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
217665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
217765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < mTracks.size(); ++i) {
217865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<Track> track = mTracks[i];
2179de070137f11d346fba77605bd76a44c040a618fcEric Laurent        if (sessionId == track->sessionId() &&
21809c5fdd83f9b9f49be35107971feb33528d60b945Glenn Kasten                !(track->mCblk->flags & CBLK_INVALID)) {
218139e94f8f723d445447fdee0822291e664b631f60Eric Laurent            result |= TRACK_SESSION;
218239e94f8f723d445447fdee0822291e664b631f60Eric Laurent            break;
218365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
218465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
218565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
218639e94f8f723d445447fdee0822291e664b631f60Eric Laurent    return result;
218765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
218865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2189de070137f11d346fba77605bd76a44c040a618fcEric Laurentuint32_t AudioFlinger::PlaybackThread::getStrategyForSession_l(int sessionId)
2190de070137f11d346fba77605bd76a44c040a618fcEric Laurent{
2191fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    // session AUDIO_SESSION_OUTPUT_MIX is placed in same strategy as MUSIC stream so that
2192de070137f11d346fba77605bd76a44c040a618fcEric Laurent    // it is moved to correct output by audio policy manager when A2DP is connected or disconnected
2193fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (sessionId == AUDIO_SESSION_OUTPUT_MIX) {
2194fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        return AudioSystem::getStrategyForStream(AUDIO_STREAM_MUSIC);
2195de070137f11d346fba77605bd76a44c040a618fcEric Laurent    }
2196de070137f11d346fba77605bd76a44c040a618fcEric Laurent    for (size_t i = 0; i < mTracks.size(); i++) {
2197de070137f11d346fba77605bd76a44c040a618fcEric Laurent        sp<Track> track = mTracks[i];
2198de070137f11d346fba77605bd76a44c040a618fcEric Laurent        if (sessionId == track->sessionId() &&
21999c5fdd83f9b9f49be35107971feb33528d60b945Glenn Kasten                !(track->mCblk->flags & CBLK_INVALID)) {
220002bbd20cece1785c223ac4ca2ddc635931a80673Glenn Kasten            return AudioSystem::getStrategyForStream(track->streamType());
2201de070137f11d346fba77605bd76a44c040a618fcEric Laurent        }
2202de070137f11d346fba77605bd76a44c040a618fcEric Laurent    }
2203fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return AudioSystem::getStrategyForStream(AUDIO_STREAM_MUSIC);
2204de070137f11d346fba77605bd76a44c040a618fcEric Laurent}
2205de070137f11d346fba77605bd76a44c040a618fcEric Laurent
220665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2207aed850d0d3b3c8cf3feaf1438076f33db2a60946Glenn KastenAudioFlinger::AudioStreamOut* AudioFlinger::PlaybackThread::getOutput() const
2208b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent{
2209b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    Mutex::Autolock _l(mLock);
2210b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    return mOutput;
2211b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent}
2212b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
2213b8ba0a979067a4efb0b3819bf17770793e41c15eEric LaurentAudioFlinger::AudioStreamOut* AudioFlinger::PlaybackThread::clearOutput()
2214b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent{
2215b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    Mutex::Autolock _l(mLock);
2216b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    AudioStreamOut *output = mOutput;
2217b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    mOutput = NULL;
221858912562617941964939a4182cda71eaeb153d4bGlenn Kasten    // FIXME FastMixer might also have a raw ptr to mOutputSink;
221958912562617941964939a4182cda71eaeb153d4bGlenn Kasten    //       must push a NULL and wait for ack
222058912562617941964939a4182cda71eaeb153d4bGlenn Kasten    mOutputSink.clear();
222158912562617941964939a4182cda71eaeb153d4bGlenn Kasten    mPipeSink.clear();
222258912562617941964939a4182cda71eaeb153d4bGlenn Kasten    mNormalSink.clear();
2223b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    return output;
2224b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent}
2225b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
2226b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent// this method must always be called either with ThreadBase mLock held or inside the thread loop
22270bf65bdde04b8e66c998ff37e2b2afafddddfa33Glenn Kastenaudio_stream_t* AudioFlinger::PlaybackThread::stream() const
2228b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent{
2229b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    if (mOutput == NULL) {
2230b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent        return NULL;
2231b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    }
2232b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    return &mOutput->stream->common;
2233b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent}
2234b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
22350bf65bdde04b8e66c998ff37e2b2afafddddfa33Glenn Kastenuint32_t AudioFlinger::PlaybackThread::activeSleepTimeUs() const
2236162b40bbaf3c3a24f61a6636bef6f80a9c0a31ddEric Laurent{
2237ab9071b8d1b375418eb797c9a790da71de644344Eric Laurent    return (uint32_t)((uint32_t)((mNormalFrameCount * 1000) / mSampleRate) * 1000);
2238162b40bbaf3c3a24f61a6636bef6f80a9c0a31ddEric Laurent}
2239162b40bbaf3c3a24f61a6636bef6f80a9c0a31ddEric Laurent
2240a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurentstatus_t AudioFlinger::PlaybackThread::setSyncEvent(const sp<SyncEvent>& event)
2241a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent{
2242a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    if (!isValidSyncEvent(event)) {
2243a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        return BAD_VALUE;
2244a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    }
2245a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
2246a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    Mutex::Autolock _l(mLock);
2247a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
2248a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    for (size_t i = 0; i < mTracks.size(); ++i) {
2249a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        sp<Track> track = mTracks[i];
2250a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        if (event->triggerSession() == track->sessionId()) {
2251d23eedca9b5a1812891c05d89850ab7ee707040dGlenn Kasten            (void) track->setSyncEvent(event);
2252a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent            return NO_ERROR;
2253a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        }
2254a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    }
2255a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
2256a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    return NAME_NOT_FOUND;
2257a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent}
2258a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
2259106e8a42038f9e90d5ff97f8ab6f1a42258bde9eGlenn Kastenbool AudioFlinger::PlaybackThread::isValidSyncEvent(const sp<SyncEvent>& event) const
2260a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent{
22610dbb356050d0db9e0043dd43045c1864a933332bGlenn Kasten    return event->type() == AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE;
2262a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent}
2263a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
226485ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kastenvoid AudioFlinger::PlaybackThread::threadLoop_removeTracks(
226585ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten        const Vector< sp<Track> >& tracksToRemove)
226644a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent{
226744a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent    size_t count = tracksToRemove.size();
226844a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent    if (CC_UNLIKELY(count)) {
226944a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent        for (size_t i = 0 ; i < count ; i++) {
227044a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent            const sp<Track>& track = tracksToRemove.itemAt(i);
227144a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent            if ((track->sharedBuffer() != 0) &&
227244a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent                    (track->mState == TrackBase::ACTIVE || track->mState == TrackBase::RESUMING)) {
227344a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent                AudioSystem::stopOutput(mId, track->streamType(), track->sessionId());
227444a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent            }
227544a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent        }
227644a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent    }
227744a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent
227844a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent}
227944a957f06400a338e7af20b3d16c4c4ae22a673cEric Laurent
228065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
228165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
228223bb8becff20449a9b1647d5a1a99b14c83f0cceGlenn KastenAudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
2283bb4350d3b9e9485ae59e084de270f86aecef8066Glenn Kasten        audio_io_handle_t id, audio_devices_t device, type_t type)
228458912562617941964939a4182cda71eaeb153d4bGlenn Kasten    :   PlaybackThread(audioFlinger, output, id, device, type),
228558912562617941964939a4182cda71eaeb153d4bGlenn Kasten        // mAudioMixer below
228658912562617941964939a4182cda71eaeb153d4bGlenn Kasten        // mFastMixer below
228758912562617941964939a4182cda71eaeb153d4bGlenn Kasten        mFastMixerFutex(0)
228858912562617941964939a4182cda71eaeb153d4bGlenn Kasten        // mOutputSink below
228958912562617941964939a4182cda71eaeb153d4bGlenn Kasten        // mPipeSink below
229058912562617941964939a4182cda71eaeb153d4bGlenn Kasten        // mNormalSink below
229158912562617941964939a4182cda71eaeb153d4bGlenn Kasten{
2292bb4350d3b9e9485ae59e084de270f86aecef8066Glenn Kasten    ALOGV("MixerThread() id=%d device=%#x type=%d", id, device, type);
229360a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten    ALOGV("mSampleRate=%u, mChannelMask=%#x, mChannelCount=%d, mFormat=%d, mFrameSize=%u, "
229458912562617941964939a4182cda71eaeb153d4bGlenn Kasten            "mFrameCount=%d, mNormalFrameCount=%d",
229558912562617941964939a4182cda71eaeb153d4bGlenn Kasten            mSampleRate, mChannelMask, mChannelCount, mFormat, mFrameSize, mFrameCount,
229658912562617941964939a4182cda71eaeb153d4bGlenn Kasten            mNormalFrameCount);
229758912562617941964939a4182cda71eaeb153d4bGlenn Kasten    mAudioMixer = new AudioMixer(mNormalFrameCount, mSampleRate);
229858912562617941964939a4182cda71eaeb153d4bGlenn Kasten
229965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // FIXME - Current mixer implementation only supports stereo output
23004fe1ec4f40b58abff6cec147aa786cb65698161aGlenn Kasten    if (mChannelCount != FCC_2) {
23014fe1ec4f40b58abff6cec147aa786cb65698161aGlenn Kasten        ALOGE("Invalid audio hardware channel count %d", mChannelCount);
230265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
230358912562617941964939a4182cda71eaeb153d4bGlenn Kasten
230458912562617941964939a4182cda71eaeb153d4bGlenn Kasten    // create an NBAIO sink for the HAL output stream, and negotiate
230558912562617941964939a4182cda71eaeb153d4bGlenn Kasten    mOutputSink = new AudioStreamOutSink(output->stream);
230658912562617941964939a4182cda71eaeb153d4bGlenn Kasten    size_t numCounterOffers = 0;
230758912562617941964939a4182cda71eaeb153d4bGlenn Kasten    const NBAIO_Format offers[1] = {Format_from_SR_C(mSampleRate, mChannelCount)};
230858912562617941964939a4182cda71eaeb153d4bGlenn Kasten    ssize_t index = mOutputSink->negotiate(offers, 1, NULL, numCounterOffers);
230958912562617941964939a4182cda71eaeb153d4bGlenn Kasten    ALOG_ASSERT(index == 0);
231058912562617941964939a4182cda71eaeb153d4bGlenn Kasten
2311300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    // initialize fast mixer depending on configuration
2312300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    bool initFastMixer;
2313300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    switch (kUseFastMixer) {
2314300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    case FastMixer_Never:
2315300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten        initFastMixer = false;
2316300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten        break;
2317300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    case FastMixer_Always:
2318300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten        initFastMixer = true;
2319300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten        break;
2320300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    case FastMixer_Static:
2321300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    case FastMixer_Dynamic:
2322300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten        initFastMixer = mFrameCount < mNormalFrameCount;
2323300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten        break;
2324300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    }
2325300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    if (initFastMixer) {
232658912562617941964939a4182cda71eaeb153d4bGlenn Kasten
232758912562617941964939a4182cda71eaeb153d4bGlenn Kasten        // create a MonoPipe to connect our submix to FastMixer
232858912562617941964939a4182cda71eaeb153d4bGlenn Kasten        NBAIO_Format format = mOutputSink->format();
23299017e5e0ebad9664bb7b6f2057e5bb29c852c64fGlenn Kasten        // This pipe depth compensates for scheduling latency of the normal mixer thread.
23309017e5e0ebad9664bb7b6f2057e5bb29c852c64fGlenn Kasten        // When it wakes up after a maximum latency, it runs a few cycles quickly before
23319017e5e0ebad9664bb7b6f2057e5bb29c852c64fGlenn Kasten        // finally blocking.  Note the pipe implementation rounds up the request to a power of 2.
23329017e5e0ebad9664bb7b6f2057e5bb29c852c64fGlenn Kasten        MonoPipe *monoPipe = new MonoPipe(mNormalFrameCount * 4, format, true /*writeCanBlock*/);
233358912562617941964939a4182cda71eaeb153d4bGlenn Kasten        const NBAIO_Format offers[1] = {format};
233458912562617941964939a4182cda71eaeb153d4bGlenn Kasten        size_t numCounterOffers = 0;
233558912562617941964939a4182cda71eaeb153d4bGlenn Kasten        ssize_t index = monoPipe->negotiate(offers, 1, NULL, numCounterOffers);
233658912562617941964939a4182cda71eaeb153d4bGlenn Kasten        ALOG_ASSERT(index == 0);
233728ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten        monoPipe->setAvgFrames((mScreenState & 1) ?
233828ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten                (monoPipe->maxFrames() * 7) / 8 : mNormalFrameCount * 2);
233958912562617941964939a4182cda71eaeb153d4bGlenn Kasten        mPipeSink = monoPipe;
234058912562617941964939a4182cda71eaeb153d4bGlenn Kasten
2341fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten#ifdef TEE_SINK_FRAMES
2342fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        // create a Pipe to archive a copy of FastMixer's output for dumpsys
2343fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        Pipe *teeSink = new Pipe(TEE_SINK_FRAMES, format);
2344fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        numCounterOffers = 0;
2345fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        index = teeSink->negotiate(offers, 1, NULL, numCounterOffers);
2346fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        ALOG_ASSERT(index == 0);
2347fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        mTeeSink = teeSink;
2348fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        PipeReader *teeSource = new PipeReader(*teeSink);
2349fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        numCounterOffers = 0;
2350fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        index = teeSource->negotiate(offers, 1, NULL, numCounterOffers);
2351fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        ALOG_ASSERT(index == 0);
2352fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        mTeeSource = teeSource;
2353fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten#endif
2354fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten
235558912562617941964939a4182cda71eaeb153d4bGlenn Kasten        // create fast mixer and configure it initially with just one fast track for our submix
235658912562617941964939a4182cda71eaeb153d4bGlenn Kasten        mFastMixer = new FastMixer();
235758912562617941964939a4182cda71eaeb153d4bGlenn Kasten        FastMixerStateQueue *sq = mFastMixer->sq();
2358399930859a75d806ce0ef124ac22025ae4ef0549Glenn Kasten#ifdef STATE_QUEUE_DUMP
2359399930859a75d806ce0ef124ac22025ae4ef0549Glenn Kasten        sq->setObserverDump(&mStateQueueObserverDump);
2360399930859a75d806ce0ef124ac22025ae4ef0549Glenn Kasten        sq->setMutatorDump(&mStateQueueMutatorDump);
2361399930859a75d806ce0ef124ac22025ae4ef0549Glenn Kasten#endif
236258912562617941964939a4182cda71eaeb153d4bGlenn Kasten        FastMixerState *state = sq->begin();
236358912562617941964939a4182cda71eaeb153d4bGlenn Kasten        FastTrack *fastTrack = &state->mFastTracks[0];
236458912562617941964939a4182cda71eaeb153d4bGlenn Kasten        // wrap the source side of the MonoPipe to make it an AudioBufferProvider
236558912562617941964939a4182cda71eaeb153d4bGlenn Kasten        fastTrack->mBufferProvider = new SourceAudioBufferProvider(new MonoPipeReader(monoPipe));
236658912562617941964939a4182cda71eaeb153d4bGlenn Kasten        fastTrack->mVolumeProvider = NULL;
236758912562617941964939a4182cda71eaeb153d4bGlenn Kasten        fastTrack->mGeneration++;
236858912562617941964939a4182cda71eaeb153d4bGlenn Kasten        state->mFastTracksGen++;
236958912562617941964939a4182cda71eaeb153d4bGlenn Kasten        state->mTrackMask = 1;
237058912562617941964939a4182cda71eaeb153d4bGlenn Kasten        // fast mixer will use the HAL output sink
237158912562617941964939a4182cda71eaeb153d4bGlenn Kasten        state->mOutputSink = mOutputSink.get();
237258912562617941964939a4182cda71eaeb153d4bGlenn Kasten        state->mOutputSinkGen++;
237358912562617941964939a4182cda71eaeb153d4bGlenn Kasten        state->mFrameCount = mFrameCount;
237458912562617941964939a4182cda71eaeb153d4bGlenn Kasten        state->mCommand = FastMixerState::COLD_IDLE;
237558912562617941964939a4182cda71eaeb153d4bGlenn Kasten        // already done in constructor initialization list
237658912562617941964939a4182cda71eaeb153d4bGlenn Kasten        //mFastMixerFutex = 0;
237758912562617941964939a4182cda71eaeb153d4bGlenn Kasten        state->mColdFutexAddr = &mFastMixerFutex;
237858912562617941964939a4182cda71eaeb153d4bGlenn Kasten        state->mColdGen++;
237958912562617941964939a4182cda71eaeb153d4bGlenn Kasten        state->mDumpState = &mFastMixerDumpState;
2380fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        state->mTeeSink = mTeeSink.get();
238158912562617941964939a4182cda71eaeb153d4bGlenn Kasten        sq->end();
238258912562617941964939a4182cda71eaeb153d4bGlenn Kasten        sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
238358912562617941964939a4182cda71eaeb153d4bGlenn Kasten
238458912562617941964939a4182cda71eaeb153d4bGlenn Kasten        // start the fast mixer
238558912562617941964939a4182cda71eaeb153d4bGlenn Kasten        mFastMixer->run("FastMixer", PRIORITY_URGENT_AUDIO);
238658912562617941964939a4182cda71eaeb153d4bGlenn Kasten        pid_t tid = mFastMixer->getTid();
2387fd4e20c226eca185fc789de761beae64855bfbbbGlenn Kasten        int err = requestPriority(getpid_cached, tid, kPriorityFastMixer);
238858912562617941964939a4182cda71eaeb153d4bGlenn Kasten        if (err != 0) {
238958912562617941964939a4182cda71eaeb153d4bGlenn Kasten            ALOGW("Policy SCHED_FIFO priority %d is unavailable for pid %d tid %d; error %d",
2390fd4e20c226eca185fc789de761beae64855bfbbbGlenn Kasten                    kPriorityFastMixer, getpid_cached, tid, err);
239158912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
239258912562617941964939a4182cda71eaeb153d4bGlenn Kasten
2393c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten#ifdef AUDIO_WATCHDOG
2394c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten        // create and start the watchdog
2395c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten        mAudioWatchdog = new AudioWatchdog();
2396c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten        mAudioWatchdog->setDump(&mAudioWatchdogDump);
2397c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten        mAudioWatchdog->run("AudioWatchdog", PRIORITY_URGENT_AUDIO);
2398c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten        tid = mAudioWatchdog->getTid();
2399fd4e20c226eca185fc789de761beae64855bfbbbGlenn Kasten        err = requestPriority(getpid_cached, tid, kPriorityFastMixer);
2400c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten        if (err != 0) {
2401c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten            ALOGW("Policy SCHED_FIFO priority %d is unavailable for pid %d tid %d; error %d",
2402fd4e20c226eca185fc789de761beae64855bfbbbGlenn Kasten                    kPriorityFastMixer, getpid_cached, tid, err);
2403c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten        }
2404c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten#endif
2405c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten
240658912562617941964939a4182cda71eaeb153d4bGlenn Kasten    } else {
240758912562617941964939a4182cda71eaeb153d4bGlenn Kasten        mFastMixer = NULL;
240858912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
2409300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten
2410300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    switch (kUseFastMixer) {
2411300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    case FastMixer_Never:
2412300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    case FastMixer_Dynamic:
2413300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten        mNormalSink = mOutputSink;
2414300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten        break;
2415300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    case FastMixer_Always:
2416300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten        mNormalSink = mPipeSink;
2417300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten        break;
2418300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    case FastMixer_Static:
2419300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten        mNormalSink = initFastMixer ? mPipeSink : mOutputSink;
2420300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten        break;
2421300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten    }
242265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
242365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
242465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::MixerThread::~MixerThread()
242565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
242658912562617941964939a4182cda71eaeb153d4bGlenn Kasten    if (mFastMixer != NULL) {
242758912562617941964939a4182cda71eaeb153d4bGlenn Kasten        FastMixerStateQueue *sq = mFastMixer->sq();
242858912562617941964939a4182cda71eaeb153d4bGlenn Kasten        FastMixerState *state = sq->begin();
242958912562617941964939a4182cda71eaeb153d4bGlenn Kasten        if (state->mCommand == FastMixerState::COLD_IDLE) {
243058912562617941964939a4182cda71eaeb153d4bGlenn Kasten            int32_t old = android_atomic_inc(&mFastMixerFutex);
243158912562617941964939a4182cda71eaeb153d4bGlenn Kasten            if (old == -1) {
243258912562617941964939a4182cda71eaeb153d4bGlenn Kasten                __futex_syscall3(&mFastMixerFutex, FUTEX_WAKE_PRIVATE, 1);
243358912562617941964939a4182cda71eaeb153d4bGlenn Kasten            }
243458912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
243558912562617941964939a4182cda71eaeb153d4bGlenn Kasten        state->mCommand = FastMixerState::EXIT;
243658912562617941964939a4182cda71eaeb153d4bGlenn Kasten        sq->end();
243758912562617941964939a4182cda71eaeb153d4bGlenn Kasten        sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
243858912562617941964939a4182cda71eaeb153d4bGlenn Kasten        mFastMixer->join();
243958912562617941964939a4182cda71eaeb153d4bGlenn Kasten        // Though the fast mixer thread has exited, it's state queue is still valid.
244058912562617941964939a4182cda71eaeb153d4bGlenn Kasten        // We'll use that extract the final state which contains one remaining fast track
244158912562617941964939a4182cda71eaeb153d4bGlenn Kasten        // corresponding to our sub-mix.
244258912562617941964939a4182cda71eaeb153d4bGlenn Kasten        state = sq->begin();
244358912562617941964939a4182cda71eaeb153d4bGlenn Kasten        ALOG_ASSERT(state->mTrackMask == 1);
244458912562617941964939a4182cda71eaeb153d4bGlenn Kasten        FastTrack *fastTrack = &state->mFastTracks[0];
244558912562617941964939a4182cda71eaeb153d4bGlenn Kasten        ALOG_ASSERT(fastTrack->mBufferProvider != NULL);
244658912562617941964939a4182cda71eaeb153d4bGlenn Kasten        delete fastTrack->mBufferProvider;
244758912562617941964939a4182cda71eaeb153d4bGlenn Kasten        sq->end(false /*didModify*/);
244858912562617941964939a4182cda71eaeb153d4bGlenn Kasten        delete mFastMixer;
2449087dd8e7232e4c009e9121ab7e8c37985522c9adGlenn Kasten#ifdef AUDIO_WATCHDOG
2450c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten        if (mAudioWatchdog != 0) {
2451c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten            mAudioWatchdog->requestExit();
2452c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten            mAudioWatchdog->requestExitAndWait();
2453c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten            mAudioWatchdog.clear();
2454c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten        }
2455087dd8e7232e4c009e9121ab7e8c37985522c9adGlenn Kasten#endif
245658912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
245765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    delete mAudioMixer;
245865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
245965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
246083efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kastenclass CpuStats {
246183efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kastenpublic:
2462190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    CpuStats();
2463190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    void sample(const String8 &title);
246483efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten#ifdef DEBUG_CPU_USAGE
246583efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kastenprivate:
2466190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    ThreadCpuUsage mCpuUsage;           // instantaneous thread CPU usage in wall clock ns
2467190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    CentralTendencyStatistics mWcStats; // statistics on thread CPU usage in wall clock ns
2468190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
2469190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    CentralTendencyStatistics mHzStats; // statistics on thread CPU usage in cycles
2470190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
2471190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    int mCpuNum;                        // thread's current CPU number
2472190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    int mCpukHz;                        // frequency of thread's current CPU in kHz
247383efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten#endif
247483efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten};
247583efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten
2476190a46f7c84e160386610c0c4cecb9767fb5503bGlenn KastenCpuStats::CpuStats()
247783efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten#ifdef DEBUG_CPU_USAGE
2478190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    : mCpuNum(-1), mCpukHz(-1)
2479190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten#endif
2480190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten{
2481190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten}
2482190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
2483190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kastenvoid CpuStats::sample(const String8 &title) {
2484190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten#ifdef DEBUG_CPU_USAGE
2485190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    // get current thread's delta CPU time in wall clock ns
2486190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    double wcNs;
2487190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    bool valid = mCpuUsage.sampleAndEnable(wcNs);
2488190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
2489190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    // record sample for wall clock statistics
2490190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    if (valid) {
2491190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        mWcStats.sample(wcNs);
2492190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    }
2493190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
2494190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    // get the current CPU number
2495190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    int cpuNum = sched_getcpu();
2496190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
2497190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    // get the current CPU frequency in kHz
2498190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    int cpukHz = mCpuUsage.getCpukHz(cpuNum);
2499190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
2500190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    // check if either CPU number or frequency changed
2501190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    if (cpuNum != mCpuNum || cpukHz != mCpukHz) {
2502190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        mCpuNum = cpuNum;
2503190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        mCpukHz = cpukHz;
2504190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        // ignore sample for purposes of cycles
2505190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        valid = false;
2506190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    }
2507190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
2508190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    // if no change in CPU number or frequency, then record sample for cycle statistics
2509190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    if (valid && mCpukHz > 0) {
2510190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        double cycles = wcNs * cpukHz * 0.000001;
2511190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        mHzStats.sample(cycles);
2512190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    }
2513190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
2514190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    unsigned n = mWcStats.n();
2515190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    // mCpuUsage.elapsed() is expensive, so don't call it every loop
251683efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten    if ((n & 127) == 1) {
2517190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        long long elapsed = mCpuUsage.elapsed();
251883efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten        if (elapsed >= DEBUG_CPU_USAGE * 1000000000LL) {
251983efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten            double perLoop = elapsed / (double) n;
252083efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten            double perLoop100 = perLoop * 0.01;
2521190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten            double perLoop1k = perLoop * 0.001;
2522190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten            double mean = mWcStats.mean();
2523190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten            double stddev = mWcStats.stddev();
2524190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten            double minimum = mWcStats.minimum();
2525190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten            double maximum = mWcStats.maximum();
2526190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten            double meanCycles = mHzStats.mean();
2527190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten            double stddevCycles = mHzStats.stddev();
2528190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten            double minCycles = mHzStats.minimum();
2529190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten            double maxCycles = mHzStats.maximum();
2530190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten            mCpuUsage.resetElapsed();
2531190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten            mWcStats.reset();
2532190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten            mHzStats.reset();
2533190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten            ALOGD("CPU usage for %s over past %.1f secs\n"
2534190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten                "  (%u mixer loops at %.1f mean ms per loop):\n"
2535190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten                "  us per mix loop: mean=%.0f stddev=%.0f min=%.0f max=%.0f\n"
2536190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten                "  %% of wall: mean=%.1f stddev=%.1f min=%.1f max=%.1f\n"
2537190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten                "  MHz: mean=%.1f, stddev=%.1f, min=%.1f max=%.1f",
2538190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten                    title.string(),
253983efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten                    elapsed * .000000001, n, perLoop * .000001,
254083efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten                    mean * .001,
254183efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten                    stddev * .001,
254283efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten                    minimum * .001,
254383efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten                    maximum * .001,
254483efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten                    mean / perLoop100,
254583efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten                    stddev / perLoop100,
254683efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten                    minimum / perLoop100,
2547190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten                    maximum / perLoop100,
2548190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten                    meanCycles / perLoop1k,
2549190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten                    stddevCycles / perLoop1k,
2550190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten                    minCycles / perLoop1k,
2551190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten                    maxCycles / perLoop1k);
2552190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten
255383efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten        }
255483efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten    }
255583efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten#endif
255683efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten};
255783efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten
255837d825e72a6c606553a745da1212590a425996d3Glenn Kastenvoid AudioFlinger::PlaybackThread::checkSilentMode_l()
255937d825e72a6c606553a745da1212590a425996d3Glenn Kasten{
256037d825e72a6c606553a745da1212590a425996d3Glenn Kasten    if (!mMasterMute) {
256137d825e72a6c606553a745da1212590a425996d3Glenn Kasten        char value[PROPERTY_VALUE_MAX];
256237d825e72a6c606553a745da1212590a425996d3Glenn Kasten        if (property_get("ro.audio.silent", value, "0") > 0) {
256337d825e72a6c606553a745da1212590a425996d3Glenn Kasten            char *endptr;
256437d825e72a6c606553a745da1212590a425996d3Glenn Kasten            unsigned long ul = strtoul(value, &endptr, 0);
256537d825e72a6c606553a745da1212590a425996d3Glenn Kasten            if (*endptr == '\0' && ul != 0) {
256637d825e72a6c606553a745da1212590a425996d3Glenn Kasten                ALOGD("Silence is golden");
256737d825e72a6c606553a745da1212590a425996d3Glenn Kasten                // The setprop command will not allow a property to be changed after
256837d825e72a6c606553a745da1212590a425996d3Glenn Kasten                // the first time it is set, so we don't have to worry about un-muting.
256937d825e72a6c606553a745da1212590a425996d3Glenn Kasten                setMasterMute_l(true);
257037d825e72a6c606553a745da1212590a425996d3Glenn Kasten            }
257137d825e72a6c606553a745da1212590a425996d3Glenn Kasten        }
257237d825e72a6c606553a745da1212590a425996d3Glenn Kasten    }
257337d825e72a6c606553a745da1212590a425996d3Glenn Kasten}
257437d825e72a6c606553a745da1212590a425996d3Glenn Kasten
2575000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kastenbool AudioFlinger::PlaybackThread::threadLoop()
257665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
257765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Vector< sp<Track> > tracksToRemove;
2578688a64030834ea2f52cc9765676ddf6aa34df767Glenn Kasten
2579000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten    standbyTime = systemTime();
2580000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
2581000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten    // MIXER
258265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    nsecs_t lastWarning = 0;
2583688a64030834ea2f52cc9765676ddf6aa34df767Glenn Kasten
2584000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten    // DUPLICATING
2585000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten    // FIXME could this be made local to while loop?
2586000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten    writeFrames = 0;
2587688a64030834ea2f52cc9765676ddf6aa34df767Glenn Kasten
258866fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten    cacheParameters_l();
2589000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten    sleepTime = idleSleepTime;
2590000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
25919f34a36d9cdb9595c288e50ffe00da038bc8abb9Glenn Kasten    if (mType == MIXER) {
25929f34a36d9cdb9595c288e50ffe00da038bc8abb9Glenn Kasten        sleepTimeShift = 0;
25939f34a36d9cdb9595c288e50ffe00da038bc8abb9Glenn Kasten    }
2594000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
259583efdd0fc08cd5aedf50b45741a8a87be8dc4b41Glenn Kasten    CpuStats cpuStats;
2596190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten    const String8 myName(String8::format("thread %p type %d TID %d", this, mType, gettid()));
259765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2598feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    acquireWakeLock();
2599feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
260065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    while (!exitPending())
260165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    {
2602190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten        cpuStats.sample(myName);
2603688a64030834ea2f52cc9765676ddf6aa34df767Glenn Kasten
260473ca0f5837d5448f7a5eb159a09cd0ebe82b4de9Glenn Kasten        Vector< sp<EffectChain> > effectChains;
260573ca0f5837d5448f7a5eb159a09cd0ebe82b4de9Glenn Kasten
260665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        processConfigEvents();
260765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
260865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        { // scope for mLock
260965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
261065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            Mutex::Autolock _l(mLock);
261165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
261265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (checkForNewParameters_l()) {
261366fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten                cacheParameters_l();
261465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
261565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2616fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten            saveOutputTracks();
2617000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
261865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // put audio hardware into standby after short delay
26193e07470f3b122097cacfe5b85cdb1359279a2f33Glenn Kasten            if (CC_UNLIKELY((!mActiveTracks.size() && systemTime() > standbyTime) ||
26201ea6d23396118a9cfe912b7b8a4e6f231e318ea2Glenn Kasten                        isSuspended())) {
262165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (!mStandby) {
2622000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
2623000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten                    threadLoop_standby();
2624000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
262565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mStandby = true;
262665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
262765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
26283e07470f3b122097cacfe5b85cdb1359279a2f33Glenn Kasten                if (!mActiveTracks.size() && mConfigEvents.isEmpty()) {
262965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    // we're about to wait, flush the binder command buffer
263065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    IPCThreadState::self()->flushCommands();
263165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2632fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten                    clearOutputTracks();
2633000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
2634d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten                    if (exitPending()) {
2635d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten                        break;
2636d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten                    }
263765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2638feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent                    releaseWakeLock_l();
263965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    // wait until we have something to do...
2640190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten                    ALOGV("%s going to sleep", myName.string());
264165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mWaitWorkCV.wait(mLock);
2642190a46f7c84e160386610c0c4cecb9767fb5503bGlenn Kasten                    ALOGV("%s waking up", myName.string());
2643feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent                    acquireWakeLock_l();
264465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2645da747447c1d4b5205469b4e94485b8769df57a97Eric Laurent                    mMixerStatus = MIXER_IDLE;
2646810280460da5000785662f6c5b0c7ff3ee0a4cb3Glenn Kasten                    mMixerStatusIgnoringFastTracks = MIXER_IDLE;
26471afc26db11b71c43f63a0f72a45a803f1a7910ddEric Laurent                    mBytesWritten = 0;
2648000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
264937d825e72a6c606553a745da1212590a425996d3Glenn Kasten                    checkSilentMode_l();
265065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2651000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten                    standbyTime = systemTime() + standbyDelay;
265265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    sleepTime = idleSleepTime;
265366fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten                    if (mType == MIXER) {
265466fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten                        sleepTimeShift = 0;
265566fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten                    }
2656000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
265765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    continue;
265865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
265965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
266065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2661810280460da5000785662f6c5b0c7ff3ee0a4cb3Glenn Kasten            // mMixerStatusIgnoringFastTracks is also updated internally
2662da747447c1d4b5205469b4e94485b8769df57a97Eric Laurent            mMixerStatus = prepareTracks_l(&tracksToRemove);
266365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
266465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // prevent any changes in effect chain list and in each effect chain
266565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // during mixing and effect process as the audio buffers could be deleted
266665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // or modified if an effect is created or deleted
2667de070137f11d346fba77605bd76a44c040a618fcEric Laurent            lockEffectChains_l(effectChains);
2668c5ac4cb3a5124860ccfc7e4ff66251c55a5595caGlenn Kasten        }
266965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2670fec279f5a0bfaa2a42e91ab6dfa0282baeee308bGlenn Kasten        if (CC_LIKELY(mMixerStatus == MIXER_TRACKS_READY)) {
2671000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten            threadLoop_mix();
267265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
2673000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten            threadLoop_sleepTime();
267465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
267565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
26761ea6d23396118a9cfe912b7b8a4e6f231e318ea2Glenn Kasten        if (isSuspended()) {
267725cbe0ecd6df8be7e40537c5d85c82f105038479Eric Laurent            sleepTime = suspendSleepTimeUs();
26781afc26db11b71c43f63a0f72a45a803f1a7910ddEric Laurent            mBytesWritten += mixBufferSize;
267965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
268004743e99e71c0da012508c7119f414027654ee94Glenn Kasten
268104743e99e71c0da012508c7119f414027654ee94Glenn Kasten        // only process effects if we're going to write
268265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (sleepTime == 0) {
2683c5ac4cb3a5124860ccfc7e4ff66251c55a5595caGlenn Kasten            for (size_t i = 0; i < effectChains.size(); i ++) {
2684c5ac4cb3a5124860ccfc7e4ff66251c55a5595caGlenn Kasten                effectChains[i]->process_l();
2685c5ac4cb3a5124860ccfc7e4ff66251c55a5595caGlenn Kasten            }
268604743e99e71c0da012508c7119f414027654ee94Glenn Kasten        }
268704743e99e71c0da012508c7119f414027654ee94Glenn Kasten
268804743e99e71c0da012508c7119f414027654ee94Glenn Kasten        // enable changes in effect chain
268904743e99e71c0da012508c7119f414027654ee94Glenn Kasten        unlockEffectChains(effectChains);
269004743e99e71c0da012508c7119f414027654ee94Glenn Kasten
269104743e99e71c0da012508c7119f414027654ee94Glenn Kasten        // sleepTime == 0 means we must write to audio hardware
269204743e99e71c0da012508c7119f414027654ee94Glenn Kasten        if (sleepTime == 0) {
2693688a64030834ea2f52cc9765676ddf6aa34df767Glenn Kasten
2694000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten            threadLoop_write();
2695000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
2696000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kastenif (mType == MIXER) {
2697000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten            // write blocked detection
269865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            nsecs_t now = systemTime();
269965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            nsecs_t delta = now - mLastWriteTime;
27005c4e818c39ac2d2739675fe907904a874f7623c5Eric Laurent            if (!mStandby && delta > maxPeriod) {
270165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mNumDelayedWrites++;
27027dede876998ff56351d495ec3a798c1b131193e8Glenn Kasten                if ((now - lastWarning) > kWarningThrottleNs) {
270399c99d00beb43b939dedc9ffb07adb89f6a85ba5Glenn Kasten#if defined(ATRACE_TAG) && (ATRACE_TAG != ATRACE_TAG_NEVER)
2704d8e6fd35ec2b59ee7d873daf1f1d9d348221c7bcGlenn Kasten                    ScopedTrace st(ATRACE_TAG, "underrun");
270599c99d00beb43b939dedc9ffb07adb89f6a85ba5Glenn Kasten#endif
27065ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block                    ALOGW("write blocked for %llu msecs, %d delayed writes, thread %p",
270765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            ns2ms(delta), mNumDelayedWrites, this);
270865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    lastWarning = now;
270965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
271065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
2711000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten}
2712688a64030834ea2f52cc9765676ddf6aa34df767Glenn Kasten
271365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mStandby = false;
271465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
271565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            usleep(sleepTime);
271665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
271765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
271858912562617941964939a4182cda71eaeb153d4bGlenn Kasten        // Finally let go of removed track(s), without the lock held
271965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // since we can't guarantee the destructors won't acquire that
272058912562617941964939a4182cda71eaeb153d4bGlenn Kasten        // same lock.  This will also mutate and push a new fast mixer state.
272158912562617941964939a4182cda71eaeb153d4bGlenn Kasten        threadLoop_removeTracks(tracksToRemove);
27221465f0c3df04c3166155a852a6a5c10069c1fd0aGlenn Kasten        tracksToRemove.clear();
2723000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
2724fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten        // FIXME I don't understand the need for this here;
2725fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten        //       it was in the original code but maybe the
2726fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten        //       assignment in saveOutputTracks() makes this unnecessary?
2727fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten        clearOutputTracks();
272865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
272965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Effect chains will be actually deleted here if they were removed from
273065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // mEffectChains list during mixing or effects processing
273165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        effectChains.clear();
273273ca0f5837d5448f7a5eb159a09cd0ebe82b4de9Glenn Kasten
273373ca0f5837d5448f7a5eb159a09cd0ebe82b4de9Glenn Kasten        // FIXME Note that the above .clear() is no longer necessary since effectChains
273473ca0f5837d5448f7a5eb159a09cd0ebe82b4de9Glenn Kasten        // is now local to this block, but will keep it for now (at least until merge done).
273565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
273665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
27379f34a36d9cdb9595c288e50ffe00da038bc8abb9Glenn Kasten    // for DuplicatingThread, standby mode is handled by the outputTracks, otherwise ...
27389f34a36d9cdb9595c288e50ffe00da038bc8abb9Glenn Kasten    if (mType == MIXER || mType == DIRECT) {
27399f34a36d9cdb9595c288e50ffe00da038bc8abb9Glenn Kasten        // put output stream into standby mode
27409f34a36d9cdb9595c288e50ffe00da038bc8abb9Glenn Kasten        if (!mStandby) {
27419f34a36d9cdb9595c288e50ffe00da038bc8abb9Glenn Kasten            mOutput->stream->common.standby(&mOutput->stream->common);
27429f34a36d9cdb9595c288e50ffe00da038bc8abb9Glenn Kasten        }
274365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
274465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2745feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    releaseWakeLock();
2746feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
2747c0b52836d07f823732f0ff98ca5ca9d7f5730cb8Glenn Kasten    ALOGV("Thread %p type %d exiting", this, mType);
274865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return false;
274965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
275065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
275158912562617941964939a4182cda71eaeb153d4bGlenn Kastenvoid AudioFlinger::MixerThread::threadLoop_removeTracks(const Vector< sp<Track> >& tracksToRemove)
275258912562617941964939a4182cda71eaeb153d4bGlenn Kasten{
275358912562617941964939a4182cda71eaeb153d4bGlenn Kasten    PlaybackThread::threadLoop_removeTracks(tracksToRemove);
275458912562617941964939a4182cda71eaeb153d4bGlenn Kasten}
275558912562617941964939a4182cda71eaeb153d4bGlenn Kasten
275658912562617941964939a4182cda71eaeb153d4bGlenn Kastenvoid AudioFlinger::MixerThread::threadLoop_write()
275758912562617941964939a4182cda71eaeb153d4bGlenn Kasten{
275858912562617941964939a4182cda71eaeb153d4bGlenn Kasten    // FIXME we should only do one push per cycle; confirm this is true
275958912562617941964939a4182cda71eaeb153d4bGlenn Kasten    // Start the fast mixer if it's not already running
276058912562617941964939a4182cda71eaeb153d4bGlenn Kasten    if (mFastMixer != NULL) {
276158912562617941964939a4182cda71eaeb153d4bGlenn Kasten        FastMixerStateQueue *sq = mFastMixer->sq();
276258912562617941964939a4182cda71eaeb153d4bGlenn Kasten        FastMixerState *state = sq->begin();
2763300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten        if (state->mCommand != FastMixerState::MIX_WRITE &&
2764300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten                (kUseFastMixer != FastMixer_Dynamic || state->mTrackMask > 1)) {
276558912562617941964939a4182cda71eaeb153d4bGlenn Kasten            if (state->mCommand == FastMixerState::COLD_IDLE) {
276658912562617941964939a4182cda71eaeb153d4bGlenn Kasten                int32_t old = android_atomic_inc(&mFastMixerFutex);
276758912562617941964939a4182cda71eaeb153d4bGlenn Kasten                if (old == -1) {
276858912562617941964939a4182cda71eaeb153d4bGlenn Kasten                    __futex_syscall3(&mFastMixerFutex, FUTEX_WAKE_PRIVATE, 1);
276958912562617941964939a4182cda71eaeb153d4bGlenn Kasten                }
2770087dd8e7232e4c009e9121ab7e8c37985522c9adGlenn Kasten#ifdef AUDIO_WATCHDOG
2771c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten                if (mAudioWatchdog != 0) {
2772c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten                    mAudioWatchdog->resume();
2773c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten                }
2774087dd8e7232e4c009e9121ab7e8c37985522c9adGlenn Kasten#endif
277558912562617941964939a4182cda71eaeb153d4bGlenn Kasten            }
277658912562617941964939a4182cda71eaeb153d4bGlenn Kasten            state->mCommand = FastMixerState::MIX_WRITE;
277758912562617941964939a4182cda71eaeb153d4bGlenn Kasten            sq->end();
277858912562617941964939a4182cda71eaeb153d4bGlenn Kasten            sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
2779300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten            if (kUseFastMixer == FastMixer_Dynamic) {
2780300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten                mNormalSink = mPipeSink;
2781300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten            }
278258912562617941964939a4182cda71eaeb153d4bGlenn Kasten        } else {
278358912562617941964939a4182cda71eaeb153d4bGlenn Kasten            sq->end(false /*didModify*/);
278458912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
278558912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
278658912562617941964939a4182cda71eaeb153d4bGlenn Kasten    PlaybackThread::threadLoop_write();
278758912562617941964939a4182cda71eaeb153d4bGlenn Kasten}
278858912562617941964939a4182cda71eaeb153d4bGlenn Kasten
2789000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten// shared by MIXER and DIRECT, overridden by DUPLICATING
2790000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kastenvoid AudioFlinger::PlaybackThread::threadLoop_write()
2791000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten{
2792952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    // FIXME rewrite to reduce number of system calls
2793952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    mLastWriteTime = systemTime();
2794952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    mInWrite = true;
279567c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent    int bytesWritten;
279658912562617941964939a4182cda71eaeb153d4bGlenn Kasten
279767c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent    // If an NBAIO sink is present, use it to write the normal mixer's submix
279867c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent    if (mNormalSink != 0) {
279958912562617941964939a4182cda71eaeb153d4bGlenn Kasten#define mBitShift 2 // FIXME
280067c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent        size_t count = mixBufferSize >> mBitShift;
280199c99d00beb43b939dedc9ffb07adb89f6a85ba5Glenn Kasten#if defined(ATRACE_TAG) && (ATRACE_TAG != ATRACE_TAG_NEVER)
280267c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent        Tracer::traceBegin(ATRACE_TAG, "write");
280399c99d00beb43b939dedc9ffb07adb89f6a85ba5Glenn Kasten#endif
280428ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten        // update the setpoint when gScreenState changes
280528ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten        uint32_t screenState = gScreenState;
280628ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten        if (screenState != mScreenState) {
280728ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten            mScreenState = screenState;
280828ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten            MonoPipe *pipe = (MonoPipe *)mPipeSink.get();
280928ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten            if (pipe != NULL) {
281028ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten                pipe->setAvgFrames((mScreenState & 1) ?
281128ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten                        (pipe->maxFrames() * 7) / 8 : mNormalFrameCount * 2);
281228ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten            }
281328ed2f93324988767b5658eba7c1fa781a275183Glenn Kasten        }
281467c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent        ssize_t framesWritten = mNormalSink->write(mMixBuffer, count);
281599c99d00beb43b939dedc9ffb07adb89f6a85ba5Glenn Kasten#if defined(ATRACE_TAG) && (ATRACE_TAG != ATRACE_TAG_NEVER)
281667c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent        Tracer::traceEnd(ATRACE_TAG);
281799c99d00beb43b939dedc9ffb07adb89f6a85ba5Glenn Kasten#endif
281867c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent        if (framesWritten > 0) {
281967c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent            bytesWritten = framesWritten << mBitShift;
282067c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent        } else {
282167c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent            bytesWritten = framesWritten;
282267c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent        }
282367c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent    // otherwise use the HAL / AudioStreamOut directly
282467c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent    } else {
282567c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent        // Direct output thread.
282667c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent        bytesWritten = (int)mOutput->stream->write(mOutput->stream, mMixBuffer, mixBufferSize);
282758912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
282858912562617941964939a4182cda71eaeb153d4bGlenn Kasten
2829d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten    if (bytesWritten > 0) {
2830d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        mBytesWritten += mixBufferSize;
2831d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten    }
2832952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    mNumWrites++;
2833952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    mInWrite = false;
2834000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten}
2835000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
283658912562617941964939a4182cda71eaeb153d4bGlenn Kastenvoid AudioFlinger::MixerThread::threadLoop_standby()
283758912562617941964939a4182cda71eaeb153d4bGlenn Kasten{
283858912562617941964939a4182cda71eaeb153d4bGlenn Kasten    // Idle the fast mixer if it's currently running
283958912562617941964939a4182cda71eaeb153d4bGlenn Kasten    if (mFastMixer != NULL) {
284058912562617941964939a4182cda71eaeb153d4bGlenn Kasten        FastMixerStateQueue *sq = mFastMixer->sq();
284158912562617941964939a4182cda71eaeb153d4bGlenn Kasten        FastMixerState *state = sq->begin();
284258912562617941964939a4182cda71eaeb153d4bGlenn Kasten        if (!(state->mCommand & FastMixerState::IDLE)) {
284358912562617941964939a4182cda71eaeb153d4bGlenn Kasten            state->mCommand = FastMixerState::COLD_IDLE;
284458912562617941964939a4182cda71eaeb153d4bGlenn Kasten            state->mColdFutexAddr = &mFastMixerFutex;
284558912562617941964939a4182cda71eaeb153d4bGlenn Kasten            state->mColdGen++;
284658912562617941964939a4182cda71eaeb153d4bGlenn Kasten            mFastMixerFutex = 0;
284758912562617941964939a4182cda71eaeb153d4bGlenn Kasten            sq->end();
284858912562617941964939a4182cda71eaeb153d4bGlenn Kasten            // BLOCK_UNTIL_PUSHED would be insufficient, as we need it to stop doing I/O now
284958912562617941964939a4182cda71eaeb153d4bGlenn Kasten            sq->push(FastMixerStateQueue::BLOCK_UNTIL_ACKED);
2850300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten            if (kUseFastMixer == FastMixer_Dynamic) {
2851300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten                mNormalSink = mOutputSink;
2852300a2ee9327c05fbf9d3a5fd595b558097c7c5e8Glenn Kasten            }
2853087dd8e7232e4c009e9121ab7e8c37985522c9adGlenn Kasten#ifdef AUDIO_WATCHDOG
2854c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten            if (mAudioWatchdog != 0) {
2855c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten                mAudioWatchdog->pause();
2856c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten            }
2857087dd8e7232e4c009e9121ab7e8c37985522c9adGlenn Kasten#endif
285858912562617941964939a4182cda71eaeb153d4bGlenn Kasten        } else {
285958912562617941964939a4182cda71eaeb153d4bGlenn Kasten            sq->end(false /*didModify*/);
286058912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
286158912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
286258912562617941964939a4182cda71eaeb153d4bGlenn Kasten    PlaybackThread::threadLoop_standby();
286358912562617941964939a4182cda71eaeb153d4bGlenn Kasten}
286458912562617941964939a4182cda71eaeb153d4bGlenn Kasten
2865000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten// shared by MIXER and DIRECT, overridden by DUPLICATING
2866000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kastenvoid AudioFlinger::PlaybackThread::threadLoop_standby()
2867000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten{
28681ea6d23396118a9cfe912b7b8a4e6f231e318ea2Glenn Kasten    ALOGV("Audio hardware entering standby, mixer %p, suspend count %d", this, mSuspended);
2869952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    mOutput->stream->common.standby(&mOutput->stream->common);
2870000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten}
2871000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
2872000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kastenvoid AudioFlinger::MixerThread::threadLoop_mix()
2873000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten{
2874952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    // obtain the presentation timestamp of the next output buffer
2875952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    int64_t pts;
2876952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    status_t status = INVALID_OPERATION;
2877000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
28782c3b2da3049627264b7c6b449a1622f002210f03John Grossman    if (mNormalSink != 0) {
28792c3b2da3049627264b7c6b449a1622f002210f03John Grossman        status = mNormalSink->getNextWriteTimestamp(&pts);
28802c3b2da3049627264b7c6b449a1622f002210f03John Grossman    } else {
28812c3b2da3049627264b7c6b449a1622f002210f03John Grossman        status = mOutputSink->getNextWriteTimestamp(&pts);
2882952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    }
2883000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
2884952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    if (status != NO_ERROR) {
2885952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        pts = AudioBufferProvider::kInvalidPTS;
2886952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    }
2887000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
2888952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    // mix buffers...
2889952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    mAudioMixer->process(pts);
2890952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    // increase sleep time progressively when application underrun condition clears.
2891952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    // Only increase sleep time if the mixer is ready for two consecutive times to avoid
2892952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    // that a steady state of alternating ready/not ready conditions keeps the sleep time
2893952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    // such that we would underrun the audio HAL.
2894952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    if ((sleepTime == 0) && (sleepTimeShift > 0)) {
2895952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        sleepTimeShift--;
2896952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    }
2897952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    sleepTime = 0;
289866fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten    standbyTime = systemTime() + standbyDelay;
2899952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    //TODO: delay standby when effects have a tail
2900000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten}
2901000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
2902000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kastenvoid AudioFlinger::MixerThread::threadLoop_sleepTime()
2903000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten{
2904952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    // If no tracks are ready, sleep once for the duration of an output
2905952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    // buffer size, then write 0s to the output
2906952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    if (sleepTime == 0) {
2907fec279f5a0bfaa2a42e91ab6dfa0282baeee308bGlenn Kasten        if (mMixerStatus == MIXER_TRACKS_ENABLED) {
2908952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            sleepTime = activeSleepTime >> sleepTimeShift;
2909952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            if (sleepTime < kMinThreadSleepTimeUs) {
2910952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                sleepTime = kMinThreadSleepTimeUs;
2911000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten            }
2912952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            // reduce sleep time in case of consecutive application underruns to avoid
2913952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            // starving the audio HAL. As activeSleepTimeUs() is larger than a buffer
2914952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            // duration we would end up writing less data than needed by the audio HAL if
2915952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            // the condition persists.
2916952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            if (sleepTimeShift < kMaxThreadSleepTimeShift) {
2917952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                sleepTimeShift++;
2918952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            }
2919952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        } else {
2920952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            sleepTime = idleSleepTime;
2921952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        }
2922f1da96d8cf60842538e00a9c950cc451f7da2c10Glenn Kasten    } else if (mBytesWritten != 0 || (mMixerStatus == MIXER_TRACKS_ENABLED)) {
2923952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        memset (mMixBuffer, 0, mixBufferSize);
2924952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        sleepTime = 0;
292585ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten        ALOGV_IF((mBytesWritten == 0 && (mMixerStatus == MIXER_TRACKS_ENABLED)),
292685ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                "anticipated start");
2927952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    }
2928952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    // TODO add standby time extension fct of effect tail
2929000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten}
2930000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
293165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// prepareTracks_l() must be called with ThreadBase::mLock held
293229c23c3aee5ae799b3480dc6876a46c46b019710Glenn KastenAudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTracks_l(
29333e07470f3b122097cacfe5b85cdb1359279a2f33Glenn Kasten        Vector< sp<Track> > *tracksToRemove)
293465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
293565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
293629c23c3aee5ae799b3480dc6876a46c46b019710Glenn Kasten    mixer_state mixerStatus = MIXER_IDLE;
293765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // find out which tracks need to be processed
29383e07470f3b122097cacfe5b85cdb1359279a2f33Glenn Kasten    size_t count = mActiveTracks.size();
293965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    size_t mixedTracks = 0;
294065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    size_t tracksWithEffect = 0;
2941288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    // counts only _active_ fast tracks
294258912562617941964939a4182cda71eaeb153d4bGlenn Kasten    size_t fastTracks = 0;
2943288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    uint32_t resetMask = 0; // bit mask of fast tracks that need to be reset
294465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
294565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    float masterVolume = mMasterVolume;
2946ea7939a079b3600cab955760839b021326f8cfc3Glenn Kasten    bool masterMute = mMasterMute;
294765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2948571d49c1c316f5e07b74ed7b5df6bdec7cbc1a14Eric Laurent    if (masterMute) {
2949571d49c1c316f5e07b74ed7b5df6bdec7cbc1a14Eric Laurent        masterVolume = 0;
2950571d49c1c316f5e07b74ed7b5df6bdec7cbc1a14Eric Laurent    }
295165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // Delegate master volume control to effect in output mix effect chain if needed
2952fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    sp<EffectChain> chain = getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX);
295365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (chain != 0) {
2954571d49c1c316f5e07b74ed7b5df6bdec7cbc1a14Eric Laurent        uint32_t v = (uint32_t)(masterVolume * (1 << 24));
2955cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent        chain->setVolume_l(&v, &v);
295665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        masterVolume = (float)((v + (1 << 23)) >> 24);
295765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        chain.clear();
295865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
295965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2960288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    // prepare a new state to push
2961288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    FastMixerStateQueue *sq = NULL;
2962288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    FastMixerState *state = NULL;
2963288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    bool didModify = false;
2964288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    FastMixerStateQueue::block_t block = FastMixerStateQueue::BLOCK_UNTIL_PUSHED;
2965288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    if (mFastMixer != NULL) {
2966288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        sq = mFastMixer->sq();
2967288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        state = sq->begin();
2968288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    }
2969288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
297065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
29713e07470f3b122097cacfe5b85cdb1359279a2f33Glenn Kasten        sp<Track> t = mActiveTracks[i].promote();
2972d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        if (t == 0) {
2973d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten            continue;
2974d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        }
297565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
29769c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten        // this const just means the local variable doesn't change
297765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Track* const track = t.get();
297858912562617941964939a4182cda71eaeb153d4bGlenn Kasten
2979288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        // process fast tracks
298058912562617941964939a4182cda71eaeb153d4bGlenn Kasten        if (track->isFastTrack()) {
2981288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
2982288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            // It's theoretically possible (though unlikely) for a fast track to be created
2983288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            // and then removed within the same normal mix cycle.  This is not a problem, as
2984288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            // the track never becomes active so it's fast mixer slot is never touched.
2985288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            // The converse, of removing an (active) track and then creating a new track
2986288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            // at the identical fast mixer slot within the same normal mix cycle,
2987288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            // is impossible because the slot isn't marked available until the end of each cycle.
2988288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            int j = track->mFastIndex;
2989893a05479c96f911d02beb0443da3ed6508143a7Glenn Kasten            ALOG_ASSERT(0 < j && j < (int)FastMixerState::kMaxFastTracks);
2990893a05479c96f911d02beb0443da3ed6508143a7Glenn Kasten            ALOG_ASSERT(!(mFastTrackAvailMask & (1 << j)));
2991288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            FastTrack *fastTrack = &state->mFastTracks[j];
2992288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
2993288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            // Determine whether the track is currently in underrun condition,
2994288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            // and whether it had a recent underrun.
29951295bb4dcff7b29c75cd23746816df12a871d72cGlenn Kasten            FastTrackDump *ftDump = &mFastMixerDumpState.mTracks[j];
29961295bb4dcff7b29c75cd23746816df12a871d72cGlenn Kasten            FastTrackUnderruns underruns = ftDump->mUnderruns;
299709474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten            uint32_t recentFull = (underruns.mBitFields.mFull -
299809474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                    track->mObservedUnderruns.mBitFields.mFull) & UNDERRUN_MASK;
299909474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten            uint32_t recentPartial = (underruns.mBitFields.mPartial -
300009474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                    track->mObservedUnderruns.mBitFields.mPartial) & UNDERRUN_MASK;
300109474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten            uint32_t recentEmpty = (underruns.mBitFields.mEmpty -
300209474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                    track->mObservedUnderruns.mBitFields.mEmpty) & UNDERRUN_MASK;
300309474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten            uint32_t recentUnderruns = recentPartial + recentEmpty;
300409474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten            track->mObservedUnderruns = underruns;
3005288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            // don't count underruns that occur while stopping or pausing
3006d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten            // or stopped which can occur when flush() is called while active
3007d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten            if (!(track->isStopping() || track->isPausing() || track->isStopped())) {
3008288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                track->mUnderrunCount += recentUnderruns;
3009288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            }
3010288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
3011d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten            // This is similar to the state machine for normal tracks,
3012288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            // with a few modifications for fast tracks.
3013d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten            bool isActive = true;
3014d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten            switch (track->mState) {
3015d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten            case TrackBase::STOPPING_1:
3016d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                // track stays active in STOPPING_1 state until first underrun
3017d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                if (recentUnderruns > 0) {
3018d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                    track->mState = TrackBase::STOPPING_2;
3019d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                }
3020d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                break;
3021d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten            case TrackBase::PAUSING:
3022288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                // ramp down is not yet implemented
3023288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                track->setPaused();
3024d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                break;
3025d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten            case TrackBase::RESUMING:
3026288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                // ramp up is not yet implemented
3027288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                track->mState = TrackBase::ACTIVE;
3028d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                break;
3029d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten            case TrackBase::ACTIVE:
303009474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                if (recentFull > 0 || recentPartial > 0) {
303109474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                    // track has provided at least some frames recently: reset retry count
303209474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                    track->mRetryCount = kMaxTrackRetries;
303309474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                }
303409474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                if (recentUnderruns == 0) {
303509474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                    // no recent underruns: stay active
303609474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                    break;
303709474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                }
303809474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                // there has recently been an underrun of some kind
303909474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                if (track->sharedBuffer() == 0) {
304009474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                    // were any of the recent underruns "empty" (no frames available)?
304109474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                    if (recentEmpty == 0) {
304209474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                        // no, then ignore the partial underruns as they are allowed indefinitely
304309474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                        break;
304409474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                    }
304509474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                    // there has recently been an "empty" underrun: decrement the retry counter
304609474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                    if (--(track->mRetryCount) > 0) {
304709474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                        break;
304809474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                    }
304909474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                    // indicate to client process that the track was disabled because of underrun;
305009474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                    // it will then automatically call start() when data is available
30519c5fdd83f9b9f49be35107971feb33528d60b945Glenn Kasten                    android_atomic_or(CBLK_DISABLED, &track->mCblk->flags);
305209474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                    // remove from active list, but state remains ACTIVE [confusing but true]
305309474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                    isActive = false;
3054d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                    break;
3055d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                }
3056d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                // fall through
3057d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten            case TrackBase::STOPPING_2:
3058d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten            case TrackBase::PAUSED:
3059d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten            case TrackBase::TERMINATED:
30602986460984580833161bdaabc7f17da1005a8961Eric Laurent            case TrackBase::STOPPED:
30612986460984580833161bdaabc7f17da1005a8961Eric Laurent            case TrackBase::FLUSHED:   // flush() while active
3062d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                // Check for presentation complete if track is inactive
3063d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                // We have consumed all the buffers of this track.
3064d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                // This would be incomplete if we auto-paused on underrun
3065d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                {
3066d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                    size_t audioHALFrames =
3067d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                            (mOutput->stream->get_latency(mOutput->stream)*mSampleRate) / 1000;
3068d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                    size_t framesWritten =
3069d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                            mBytesWritten / audio_stream_frame_size(&mOutput->stream->common);
3070291f824e02ff517a34cfe50220b4e2b402ee998dGlenn Kasten                    if (!(mStandby || track->presentationComplete(framesWritten, audioHALFrames))) {
3071d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                        // track stays in active list until presentation is complete
3072d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                        break;
3073d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                    }
3074d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                }
3075d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                if (track->isStopping_2()) {
3076d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                    track->mState = TrackBase::STOPPED;
3077d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                }
3078d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                if (track->isStopped()) {
3079d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                    // Can't reset directly, as fast mixer is still polling this track
3080d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                    //   track->reset();
3081d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                    // So instead mark this track as needing to be reset after push with ack
3082d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                    resetMask |= 1 << i;
3083d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                }
3084d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                isActive = false;
3085d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                break;
3086d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten            case TrackBase::IDLE:
3087d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten            default:
3088d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                LOG_FATAL("unexpected track state %d", track->mState);
3089288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            }
3090288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
3091288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            if (isActive) {
3092288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                // was it previously inactive?
3093288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                if (!(state->mTrackMask & (1 << j))) {
3094288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                    ExtendedAudioBufferProvider *eabp = track;
3095288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                    VolumeProvider *vp = track;
3096288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                    fastTrack->mBufferProvider = eabp;
3097288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                    fastTrack->mVolumeProvider = vp;
3098288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                    fastTrack->mSampleRate = track->mSampleRate;
3099288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                    fastTrack->mChannelMask = track->mChannelMask;
3100288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                    fastTrack->mGeneration++;
3101288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                    state->mTrackMask |= 1 << j;
3102288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                    didModify = true;
3103288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                    // no acknowledgement required for newly active tracks
3104288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                }
3105288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                // cache the combined master volume and stream type volume for fast mixer; this
3106288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                // lacks any synchronization or barrier so VolumeProvider may read a stale value
3107288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                track->mCachedVolume = track->isMuted() ?
3108288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                        0 : masterVolume * mStreamTypes[track->streamType()].volume;
3109288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                ++fastTracks;
3110288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            } else {
3111288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                // was it previously active?
3112288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                if (state->mTrackMask & (1 << j)) {
3113288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                    fastTrack->mBufferProvider = NULL;
3114288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                    fastTrack->mGeneration++;
3115288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                    state->mTrackMask &= ~(1 << j);
3116288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                    didModify = true;
3117288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                    // If any fast tracks were removed, we must wait for acknowledgement
3118288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                    // because we're about to decrement the last sp<> on those tracks.
3119288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                    block = FastMixerStateQueue::BLOCK_UNTIL_ACKED;
3120d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                } else {
3121d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                    LOG_FATAL("fast track %d should have been active", j);
3122288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                }
3123d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                tracksToRemove->add(track);
3124288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                // Avoids a misleading display in dumpsys
312509474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten                track->mObservedUnderruns.mBitFields.mMostRecent = UNDERRUN_FULL;
312658912562617941964939a4182cda71eaeb153d4bGlenn Kasten            }
312758912562617941964939a4182cda71eaeb153d4bGlenn Kasten            continue;
312858912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
312958912562617941964939a4182cda71eaeb153d4bGlenn Kasten
313058912562617941964939a4182cda71eaeb153d4bGlenn Kasten        {   // local variable scope to avoid goto warning
313158912562617941964939a4182cda71eaeb153d4bGlenn Kasten
313265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        audio_track_cblk_t* cblk = track->cblk();
313365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
313465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // The first time a track is added we wait
313565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // for all its buffers to be filled before processing it
31369c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten        int name = track->name();
3137a47b69c6f7c6fe0044ebcb2d0790ce3548de56fdEric Laurent        // make sure that we have enough frames to mix one full buffer.
3138a47b69c6f7c6fe0044ebcb2d0790ce3548de56fdEric Laurent        // enforce this condition only once to enable draining the buffer in case the client
3139a47b69c6f7c6fe0044ebcb2d0790ce3548de56fdEric Laurent        // app does not call stop() and relies on underrun to stop:
3140da747447c1d4b5205469b4e94485b8769df57a97Eric Laurent        // hence the test on (mMixerStatus == MIXER_TRACKS_READY) meaning the track was mixed
3141a47b69c6f7c6fe0044ebcb2d0790ce3548de56fdEric Laurent        // during last round
31423dbe3201479828e84abe02e1fdd0a5d414c0ddb8Eric Laurent        uint32_t minFrames = 1;
314383faee053cfd4251dbb591b62039f563ffdac399Eric Laurent        if ((track->sharedBuffer() == 0) && !track->isStopped() && !track->isPausing() &&
3144810280460da5000785662f6c5b0c7ff3ee0a4cb3Glenn Kasten                (mMixerStatusIgnoringFastTracks == MIXER_TRACKS_READY)) {
31453b16c766d1ae2cfd8487e8ffb2b23936fc0a8e17Glenn Kasten            if (t->sampleRate() == mSampleRate) {
314658912562617941964939a4182cda71eaeb153d4bGlenn Kasten                minFrames = mNormalFrameCount;
31473dbe3201479828e84abe02e1fdd0a5d414c0ddb8Eric Laurent            } else {
3148071ccd5a9702500f3f7d62ef881300914926184dEric Laurent                // +1 for rounding and +1 for additional sample needed for interpolation
314958912562617941964939a4182cda71eaeb153d4bGlenn Kasten                minFrames = (mNormalFrameCount * t->sampleRate()) / mSampleRate + 1 + 1;
3150071ccd5a9702500f3f7d62ef881300914926184dEric Laurent                // add frames already consumed but not yet released by the resampler
3151ea7939a079b3600cab955760839b021326f8cfc3Glenn Kasten                // because cblk->framesReady() will include these frames
3152071ccd5a9702500f3f7d62ef881300914926184dEric Laurent                minFrames += mAudioMixer->getUnreleasedFrames(track->name());
3153071ccd5a9702500f3f7d62ef881300914926184dEric Laurent                // the minimum track buffer size is normally twice the number of frames necessary
3154071ccd5a9702500f3f7d62ef881300914926184dEric Laurent                // to fill one buffer and the resampler should not leave more than one buffer worth
3155071ccd5a9702500f3f7d62ef881300914926184dEric Laurent                // of unreleased frames after each pass, but just in case...
3156c1dc1cb1d1eaf84e88669f1a5f22579a0d9237c2Steve Block                ALOG_ASSERT(minFrames <= cblk->frameCount);
31573dbe3201479828e84abe02e1fdd0a5d414c0ddb8Eric Laurent            }
31583dbe3201479828e84abe02e1fdd0a5d414c0ddb8Eric Laurent        }
31594ff14bae91075eb274eb1c2975982358946e7e63John Grossman        if ((track->framesReady() >= minFrames) && track->isReady() &&
316065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                !track->isPaused() && !track->isTerminated())
316165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        {
316285ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten            ALOGVV("track %d u=%08x, s=%08x [OK] on thread %p", name, cblk->user, cblk->server,
316385ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                    this);
316465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
316565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mixedTracks++;
316665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
316765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // track->mainBuffer() != mMixBuffer means there is an effect chain
316865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // connected to the track
316965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            chain.clear();
317065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (track->mainBuffer() != mMixBuffer) {
317165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                chain = getEffectChain_l(track->sessionId());
317265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // Delegate volume control to effect in track effect chain if needed
317365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (chain != 0) {
317465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    tracksWithEffect++;
317565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                } else {
317685ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                    ALOGW("prepareTracks_l(): track %d attached to effect but no chain found on "
317785ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                            "session %d",
31789c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten                            name, track->sessionId());
317965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
318065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
318165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
318265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
318365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            int param = AudioMixer::VOLUME;
318465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (track->mFillingUpStatus == Track::FS_FILLED) {
318565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // no ramp for the first volume setting
318665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                track->mFillingUpStatus = Track::FS_ACTIVE;
318765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (track->mState == TrackBase::RESUMING) {
318865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    track->mState = TrackBase::ACTIVE;
318965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    param = AudioMixer::RAMP_VOLUME;
319065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
31919c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten                mAudioMixer->setParameter(name, AudioMixer::RESAMPLE, AudioMixer::RESET, NULL);
319265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else if (cblk->server != 0) {
319365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // If the track is stopped before the first frame was mixed,
319465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // do not apply ramp
319565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                param = AudioMixer::RAMP_VOLUME;
319665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
319765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
319865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // compute volume for this track
3199e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent            uint32_t vl, vr, va;
32008569f0d3bf4c6787707e348a7cf73b9c4199cb32Eric Laurent            if (track->isMuted() || track->isPausing() ||
320102bbd20cece1785c223ac4ca2ddc635931a80673Glenn Kasten                mStreamTypes[track->streamType()].mute) {
3202e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent                vl = vr = va = 0;
320365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (track->isPausing()) {
320465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    track->setPaused();
320565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
320665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else {
3207e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent
320865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // read original volumes with volume control
320902bbd20cece1785c223ac4ca2ddc635931a80673Glenn Kasten                float typeVolume = mStreamTypes[track->streamType()].volume;
321065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                float v = masterVolume * typeVolume;
321183d86538c4c479a9225c75ab27938e8f05abb9c8Glenn Kasten                uint32_t vlr = cblk->getVolumeLR();
3212b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten                vl = vlr & 0xFFFF;
3213b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten                vr = vlr >> 16;
3214b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten                // track volumes come from shared memory, so can't be trusted and must be clamped
3215b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten                if (vl > MAX_GAIN_INT) {
3216b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten                    ALOGV("Track left volume out of range: %04X", vl);
3217b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten                    vl = MAX_GAIN_INT;
3218b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten                }
3219b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten                if (vr > MAX_GAIN_INT) {
3220b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten                    ALOGV("Track right volume out of range: %04X", vr);
3221b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten                    vr = MAX_GAIN_INT;
3222b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten                }
3223b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten                // now apply the master volume and stream type volume
3224b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten                vl = (uint32_t)(v * vl) << 12;
3225b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten                vr = (uint32_t)(v * vr) << 12;
3226b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten                // assuming master volume and stream type volume each go up to 1.0,
3227b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten                // vl and vr are now in 8.24 format
322865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
322905632a5fa4b88ca474294887fc92a9fcdf0e2352Glenn Kasten                uint16_t sendLevel = cblk->getSendLevel_U4_12();
323005632a5fa4b88ca474294887fc92a9fcdf0e2352Glenn Kasten                // send level comes from shared memory and so may be corrupt
32313b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten                if (sendLevel > MAX_GAIN_INT) {
323205632a5fa4b88ca474294887fc92a9fcdf0e2352Glenn Kasten                    ALOGV("Track send level out of range: %04X", sendLevel);
3233b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten                    sendLevel = MAX_GAIN_INT;
323405632a5fa4b88ca474294887fc92a9fcdf0e2352Glenn Kasten                }
323505632a5fa4b88ca474294887fc92a9fcdf0e2352Glenn Kasten                va = (uint32_t)(v * sendLevel);
3236e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent            }
3237e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent            // Delegate volume control to effect in track effect chain if needed
3238e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent            if (chain != 0 && chain->setVolume_l(&vl, &vr)) {
3239e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent                // Do not ramp volume if volume is controlled by effect
3240e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent                param = AudioMixer::VOLUME;
3241e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent                track->mHasVolumeController = true;
3242e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent            } else {
3243e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent                // force no volume ramp when volume controller was just disabled or removed
3244e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent                // from effect chain to avoid volume spike
3245e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent                if (track->mHasVolumeController) {
324665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    param = AudioMixer::VOLUME;
324765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
3248e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent                track->mHasVolumeController = false;
324965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
325065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3251e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent            // Convert volumes from 8.24 to 4.12 format
3252b1cf75c4935001f61057989ee3cf27bbf09ecd9cGlenn Kasten            // This additional clamping is needed in case chain->setVolume_l() overshot
32533b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten            vl = (vl + (1 << 11)) >> 12;
3254d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten            if (vl > MAX_GAIN_INT) {
3255d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten                vl = MAX_GAIN_INT;
3256d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten            }
32573b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten            vr = (vr + (1 << 11)) >> 12;
3258d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten            if (vr > MAX_GAIN_INT) {
3259d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten                vr = MAX_GAIN_INT;
3260d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten            }
3261e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent
3262d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten            if (va > MAX_GAIN_INT) {
3263d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten                va = MAX_GAIN_INT;   // va is uint32_t, so no need to check for -
3264d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten            }
3265e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent
326665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // XXX: these things DON'T need to be done each time
32679c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten            mAudioMixer->setBufferProvider(name, track);
32689c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten            mAudioMixer->enable(name);
326965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
32703b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten            mAudioMixer->setParameter(name, param, AudioMixer::VOLUME0, (void *)vl);
32713b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten            mAudioMixer->setParameter(name, param, AudioMixer::VOLUME1, (void *)vr);
32723b81acab52b7140c1b8b20be2d67be3e221637e7Glenn Kasten            mAudioMixer->setParameter(name, param, AudioMixer::AUXLEVEL, (void *)va);
327365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mAudioMixer->setParameter(
32749c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten                name,
327565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                AudioMixer::TRACK,
327665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                AudioMixer::FORMAT, (void *)track->format());
327765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mAudioMixer->setParameter(
32789c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten                name,
327965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                AudioMixer::TRACK,
32800d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi                AudioMixer::CHANNEL_MASK, (void *)track->channelMask());
328165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mAudioMixer->setParameter(
32829c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten                name,
328365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                AudioMixer::RESAMPLE,
328465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                AudioMixer::SAMPLE_RATE,
328565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                (void *)(cblk->sampleRate));
328665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mAudioMixer->setParameter(
32879c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten                name,
328865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                AudioMixer::TRACK,
328965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                AudioMixer::MAIN_BUFFER, (void *)track->mainBuffer());
329065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mAudioMixer->setParameter(
32919c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten                name,
329265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                AudioMixer::TRACK,
329365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                AudioMixer::AUX_BUFFER, (void *)track->auxBuffer());
329465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
329565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // reset retry count
329665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            track->mRetryCount = kMaxTrackRetries;
3297ea7939a079b3600cab955760839b021326f8cfc3Glenn Kasten
32982774144fa8283f1a7b43e17a53c97dec0c366dd3Eric Laurent            // If one track is ready, set the mixer ready if:
32992774144fa8283f1a7b43e17a53c97dec0c366dd3Eric Laurent            //  - the mixer was not ready during previous round OR
33002774144fa8283f1a7b43e17a53c97dec0c366dd3Eric Laurent            //  - no other track is not ready
3301810280460da5000785662f6c5b0c7ff3ee0a4cb3Glenn Kasten            if (mMixerStatusIgnoringFastTracks != MIXER_TRACKS_READY ||
33022774144fa8283f1a7b43e17a53c97dec0c366dd3Eric Laurent                    mixerStatus != MIXER_TRACKS_ENABLED) {
33032774144fa8283f1a7b43e17a53c97dec0c366dd3Eric Laurent                mixerStatus = MIXER_TRACKS_READY;
33042774144fa8283f1a7b43e17a53c97dec0c366dd3Eric Laurent            }
330565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
330691b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent            // clear effect chain input buffer if an active track underruns to avoid sending
330791b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent            // previous audio buffer again to effects
330891b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent            chain = getEffectChain_l(track->sessionId());
330991b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent            if (chain != 0) {
331091b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent                chain->clearInputBuffer();
331191b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent            }
331291b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent
331385ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten            ALOGVV("track %d u=%08x, s=%08x [NOT READY] on thread %p", name, cblk->user,
331485ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                    cblk->server, this);
3315842c5d9553f3f8e97d04ed1bd0d37e4851240654Glenn Kasten            if ((track->sharedBuffer() != 0) || track->isTerminated() ||
331683faee053cfd4251dbb591b62039f563ffdac399Eric Laurent                    track->isStopped() || track->isPaused()) {
331765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // We have consumed all the buffers of this track.
331865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // Remove it from the list of active tracks.
3319a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                // TODO: use actual buffer filling status instead of latency when available from
3320a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                // audio HAL
3321a045dcafd2b77036210f5b72e79d745ad4c1b848Jean-Michel Trivi                size_t audioHALFrames = (latency_l() * mSampleRate) / 1000;
3322a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                size_t framesWritten =
3323a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                        mBytesWritten / audio_stream_frame_size(&mOutput->stream->common);
3324291f824e02ff517a34cfe50220b4e2b402ee998dGlenn Kasten                if (mStandby || track->presentationComplete(framesWritten, audioHALFrames)) {
33252986460984580833161bdaabc7f17da1005a8961Eric Laurent                    if (track->isStopped()) {
33262986460984580833161bdaabc7f17da1005a8961Eric Laurent                        track->reset();
33272986460984580833161bdaabc7f17da1005a8961Eric Laurent                    }
3328a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                    tracksToRemove->add(track);
3329a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                }
333065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else {
3331bf0d21fb1310e8677caa53b90e8c3aecebc7fc13Glenn Kasten                track->mUnderrunCount++;
333265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // No buffers for this track. Give it a few chances to
333365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // fill a buffer, then remove it from active list.
3334842c5d9553f3f8e97d04ed1bd0d37e4851240654Glenn Kasten                if (--(track->mRetryCount) <= 0) {
3335842c5d9553f3f8e97d04ed1bd0d37e4851240654Glenn Kasten                    ALOGV("BUFFER TIMEOUT: remove(%d) from active list on thread %p", name, this);
333665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    tracksToRemove->add(track);
3337288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                    // indicate to client process that the track was disabled because of underrun;
3338288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                    // it will then automatically call start() when data is available
33399c5fdd83f9b9f49be35107971feb33528d60b945Glenn Kasten                    android_atomic_or(CBLK_DISABLED, &cblk->flags);
33402774144fa8283f1a7b43e17a53c97dec0c366dd3Eric Laurent                // If one track is not ready, mark the mixer also not ready if:
33412774144fa8283f1a7b43e17a53c97dec0c366dd3Eric Laurent                //  - the mixer was ready during previous round OR
33422774144fa8283f1a7b43e17a53c97dec0c366dd3Eric Laurent                //  - no other track is ready
3343810280460da5000785662f6c5b0c7ff3ee0a4cb3Glenn Kasten                } else if (mMixerStatusIgnoringFastTracks == MIXER_TRACKS_READY ||
33442774144fa8283f1a7b43e17a53c97dec0c366dd3Eric Laurent                                mixerStatus != MIXER_TRACKS_READY) {
334565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mixerStatus = MIXER_TRACKS_ENABLED;
334665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
334765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
33489c56d4ae6212c21ce5fd71ed534eb195983a07c1Glenn Kasten            mAudioMixer->disable(name);
334965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
335058912562617941964939a4182cda71eaeb153d4bGlenn Kasten
335158912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }   // local variable scope to avoid goto warning
335258912562617941964939a4182cda71eaeb153d4bGlenn Kastentrack_is_ready: ;
335358912562617941964939a4182cda71eaeb153d4bGlenn Kasten
335465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
335565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3356288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    // Push the new FastMixer state if necessary
3357c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten    bool pauseAudioWatchdog = false;
3358288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    if (didModify) {
3359288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        state->mFastTracksGen++;
3360288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        // if the fast mixer was active, but now there are no fast tracks, then put it in cold idle
3361288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        if (kUseFastMixer == FastMixer_Dynamic &&
3362288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                state->mCommand == FastMixerState::MIX_WRITE && state->mTrackMask <= 1) {
3363288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            state->mCommand = FastMixerState::COLD_IDLE;
3364288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            state->mColdFutexAddr = &mFastMixerFutex;
3365288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            state->mColdGen++;
3366288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            mFastMixerFutex = 0;
3367288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            if (kUseFastMixer == FastMixer_Dynamic) {
3368288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten                mNormalSink = mOutputSink;
3369288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            }
3370288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            // If we go into cold idle, need to wait for acknowledgement
3371288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            // so that fast mixer stops doing I/O.
3372288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            block = FastMixerStateQueue::BLOCK_UNTIL_ACKED;
3373c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten            pauseAudioWatchdog = true;
3374288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        }
3375288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        sq->end();
3376288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    }
3377288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    if (sq != NULL) {
3378288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        sq->end(didModify);
3379288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        sq->push(block);
3380288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    }
3381087dd8e7232e4c009e9121ab7e8c37985522c9adGlenn Kasten#ifdef AUDIO_WATCHDOG
3382c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten    if (pauseAudioWatchdog && mAudioWatchdog != 0) {
3383c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten        mAudioWatchdog->pause();
3384c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten    }
3385087dd8e7232e4c009e9121ab7e8c37985522c9adGlenn Kasten#endif
3386288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
3387288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    // Now perform the deferred reset on fast tracks that have stopped
3388288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    while (resetMask != 0) {
3389288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        size_t i = __builtin_ctz(resetMask);
3390288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        ALOG_ASSERT(i < count);
3391288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        resetMask &= ~(1 << i);
3392288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        sp<Track> t = mActiveTracks[i].promote();
3393d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        if (t == 0) {
3394d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten            continue;
3395d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        }
3396288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        Track* track = t.get();
3397288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        ALOG_ASSERT(track->isFastTrack() && track->isStopped());
3398288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        track->reset();
3399288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    }
340058912562617941964939a4182cda71eaeb153d4bGlenn Kasten
340165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // remove all the tracks that need to be...
340265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    count = tracksToRemove->size();
3403f6b1678f8f508b447155a81b44e214475ab634a8Glenn Kasten    if (CC_UNLIKELY(count)) {
340465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (size_t i=0 ; i<count ; i++) {
340565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            const sp<Track>& track = tracksToRemove->itemAt(i);
340665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mActiveTracks.remove(track);
340765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (track->mainBuffer() != mMixBuffer) {
340865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                chain = getEffectChain_l(track->sessionId());
340965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (chain != 0) {
341085ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                    ALOGV("stopping track on chain %p for session Id: %d", chain.get(),
341185ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                            track->sessionId());
3412b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent                    chain->decActiveTrackCnt();
341365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
341465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
341565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (track->isTerminated()) {
3416b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent                removeTrack_l(track);
341765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
341865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
341965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
342065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
342165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // mix buffer must be cleared if all tracks are connected to an
342265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // effect chain as in this case the mixer will not write to
342365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // mix buffer and track effects will accumulate into it
342485ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten    if ((mixedTracks != 0 && mixedTracks == tracksWithEffect) ||
342585ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten            (mixedTracks == 0 && fastTracks > 0)) {
342658912562617941964939a4182cda71eaeb153d4bGlenn Kasten        // FIXME as a performance optimization, should remember previous zero status
342758912562617941964939a4182cda71eaeb153d4bGlenn Kasten        memset(mMixBuffer, 0, mNormalFrameCount * mChannelCount * sizeof(int16_t));
342865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
342965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
343058912562617941964939a4182cda71eaeb153d4bGlenn Kasten    // if any fast tracks, then status is ready
3431810280460da5000785662f6c5b0c7ff3ee0a4cb3Glenn Kasten    mMixerStatusIgnoringFastTracks = mixerStatus;
343258912562617941964939a4182cda71eaeb153d4bGlenn Kasten    if (fastTracks > 0) {
343358912562617941964939a4182cda71eaeb153d4bGlenn Kasten        mixerStatus = MIXER_TRACKS_READY;
343458912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
343565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mixerStatus;
343665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
343765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
343866fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten/*
343966fcab972e9218d47c58a915f391b2f48a09903aGlenn KastenThe derived values that are cached:
344066fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten - mixBufferSize from frame count * frame size
344166fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten - activeSleepTime from activeSleepTimeUs()
344266fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten - idleSleepTime from idleSleepTimeUs()
344366fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten - standbyDelay from mActiveSleepTimeUs (DIRECT only)
344466fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten - maxPeriod from frame count and sample rate (MIXER only)
344566fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten
344666fcab972e9218d47c58a915f391b2f48a09903aGlenn KastenThe parameters that affect these derived values are:
344766fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten - frame count
344866fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten - frame size
344966fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten - sample rate
345066fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten - device type: A2DP or not
345166fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten - device latency
345266fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten - format: PCM or not
345366fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten - active sleep time
345466fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten - idle sleep time
345566fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten*/
345666fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten
345766fcab972e9218d47c58a915f391b2f48a09903aGlenn Kastenvoid AudioFlinger::PlaybackThread::cacheParameters_l()
345866fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten{
345958912562617941964939a4182cda71eaeb153d4bGlenn Kasten    mixBufferSize = mNormalFrameCount * mFrameSize;
346066fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten    activeSleepTime = activeSleepTimeUs();
346166fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten    idleSleepTime = idleSleepTimeUs();
346266fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten}
346366fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten
346422167855ff9af7b13fda669ca27c67a037a7d585Eric Laurentvoid AudioFlinger::PlaybackThread::invalidateTracks(audio_stream_type_t streamType)
346565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
34663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV ("MixerThread::invalidateTracks() mixer %p, streamType %d, mTracks.size %d",
3467de070137f11d346fba77605bd76a44c040a618fcEric Laurent            this,  streamType, mTracks.size());
346865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
3469de070137f11d346fba77605bd76a44c040a618fcEric Laurent
347065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    size_t size = mTracks.size();
347165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < size; i++) {
347265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<Track> t = mTracks[i];
347302bbd20cece1785c223ac4ca2ddc635931a80673Glenn Kasten        if (t->streamType() == streamType) {
34749c5fdd83f9b9f49be35107971feb33528d60b945Glenn Kasten            android_atomic_or(CBLK_INVALID, &t->mCblk->flags);
347565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            t->mCblk->cv.signal();
347665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
347765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
347865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
347965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
348065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// getTrackName_l() must be called with ThreadBase::mLock held
3481fe3156ec6fd9fa57dde913fd8567530d095a6550Jean-Michel Triviint AudioFlinger::MixerThread::getTrackName_l(audio_channel_mask_t channelMask, int sessionId)
348265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
3483fe3156ec6fd9fa57dde913fd8567530d095a6550Jean-Michel Trivi    return mAudioMixer->getTrackName(channelMask, sessionId);
348465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
348565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
348665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// deleteTrackName_l() must be called with ThreadBase::mLock held
348765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::MixerThread::deleteTrackName_l(int name)
348865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
34893856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("remove track (%d) and delete from mixer", name);
349065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mAudioMixer->deleteTrackName(name);
349165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
349265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
349365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// checkForNewParameters_l() must be called with ThreadBase::mLock held
349465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool AudioFlinger::MixerThread::checkForNewParameters_l()
349565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
349658912562617941964939a4182cda71eaeb153d4bGlenn Kasten    // if !&IDLE, holds the FastMixer state to restore after new parameters processed
349758912562617941964939a4182cda71eaeb153d4bGlenn Kasten    FastMixerState::Command previousCommand = FastMixerState::HOT_IDLE;
349865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool reconfig = false;
349965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
350065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    while (!mNewParameters.isEmpty()) {
350158912562617941964939a4182cda71eaeb153d4bGlenn Kasten
350258912562617941964939a4182cda71eaeb153d4bGlenn Kasten        if (mFastMixer != NULL) {
350358912562617941964939a4182cda71eaeb153d4bGlenn Kasten            FastMixerStateQueue *sq = mFastMixer->sq();
350458912562617941964939a4182cda71eaeb153d4bGlenn Kasten            FastMixerState *state = sq->begin();
350558912562617941964939a4182cda71eaeb153d4bGlenn Kasten            if (!(state->mCommand & FastMixerState::IDLE)) {
350658912562617941964939a4182cda71eaeb153d4bGlenn Kasten                previousCommand = state->mCommand;
350758912562617941964939a4182cda71eaeb153d4bGlenn Kasten                state->mCommand = FastMixerState::HOT_IDLE;
350858912562617941964939a4182cda71eaeb153d4bGlenn Kasten                sq->end();
350958912562617941964939a4182cda71eaeb153d4bGlenn Kasten                sq->push(FastMixerStateQueue::BLOCK_UNTIL_ACKED);
351058912562617941964939a4182cda71eaeb153d4bGlenn Kasten            } else {
351158912562617941964939a4182cda71eaeb153d4bGlenn Kasten                sq->end(false /*didModify*/);
351258912562617941964939a4182cda71eaeb153d4bGlenn Kasten            }
351358912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
351458912562617941964939a4182cda71eaeb153d4bGlenn Kasten
351565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status_t status = NO_ERROR;
351665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        String8 keyValuePair = mNewParameters[0];
351765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        AudioParameter param = AudioParameter(keyValuePair);
351865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int value;
351965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
352065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (param.getInt(String8(AudioParameter::keySamplingRate), value) == NO_ERROR) {
352165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            reconfig = true;
352265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
352365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (param.getInt(String8(AudioParameter::keyFormat), value) == NO_ERROR) {
352458f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten            if ((audio_format_t) value != AUDIO_FORMAT_PCM_16_BIT) {
352565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                status = BAD_VALUE;
352665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else {
352765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                reconfig = true;
352865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
352965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
353065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (param.getInt(String8(AudioParameter::keyChannels), value) == NO_ERROR) {
3531fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin            if (value != AUDIO_CHANNEL_OUT_STEREO) {
353265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                status = BAD_VALUE;
353365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else {
353465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                reconfig = true;
353565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
353665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
353765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (param.getInt(String8(AudioParameter::keyFrameCount), value) == NO_ERROR) {
353865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // do not accept frame count changes if tracks are open as the track buffer
3539362c4e697d8e9c034e964ac7b40227e054491547Glenn Kasten            // size depends on frame count and correct behavior would not be guaranteed
354065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // if frame count is changed after track creation
354165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (!mTracks.isEmpty()) {
354265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                status = INVALID_OPERATION;
354365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else {
354465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                reconfig = true;
354565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
354665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
354765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) {
3548d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten#ifdef ADD_BATTERY_DATA
35499ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang            // when changing the audio output device, call addBatteryData to notify
35509ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang            // the change
3551f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent            if (mOutDevice != value) {
35529ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                uint32_t params = 0;
35539ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                // check whether speaker is on
3554fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                if (value & AUDIO_DEVICE_OUT_SPEAKER) {
35559ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                    params |= IMediaPlayerService::kBatteryDataSpeakerOn;
35569ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                }
35579ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
3558bb4350d3b9e9485ae59e084de270f86aecef8066Glenn Kasten                audio_devices_t deviceWithoutSpeaker
3559fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                    = AUDIO_DEVICE_OUT_ALL & ~AUDIO_DEVICE_OUT_SPEAKER;
35609ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                // check if any other device (except speaker) is on
35619ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                if (value & deviceWithoutSpeaker ) {
35629ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                    params |= IMediaPlayerService::kBatteryDataOtherAudioDeviceOn;
35639ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                }
35649ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
35659ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                if (params != 0) {
35669ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                    addBatteryData(params);
35679ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                }
35689ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang            }
3569d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten#endif
35709ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
357165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // forward device change to effects that have requested to be
357265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // aware of attached audio device.
3573f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent            mOutDevice = value;
357465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            for (size_t i = 0; i < mEffectChains.size(); i++) {
3575f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent                mEffectChains[i]->setDevice_l(mOutDevice);
357665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
357765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
357865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
357965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (status == NO_ERROR) {
3580799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin            status = mOutput->stream->common.set_parameters(&mOutput->stream->common,
3581fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                                    keyValuePair.string());
358265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (!mStandby && status == INVALID_OPERATION) {
3583e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                mOutput->stream->common.standby(&mOutput->stream->common);
3584e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                mStandby = true;
3585e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                mBytesWritten = 0;
3586e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                status = mOutput->stream->common.set_parameters(&mOutput->stream->common,
3587fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                                       keyValuePair.string());
358865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
358965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (status == NO_ERROR && reconfig) {
359065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                delete mAudioMixer;
3591e9dd0176933d6233916c84e18f3e8c0d644ca05dGlenn Kasten                // for safety in case readOutputParameters() accesses mAudioMixer (it doesn't)
3592e9dd0176933d6233916c84e18f3e8c0d644ca05dGlenn Kasten                mAudioMixer = NULL;
359365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                readOutputParameters();
359458912562617941964939a4182cda71eaeb153d4bGlenn Kasten                mAudioMixer = new AudioMixer(mNormalFrameCount, mSampleRate);
359565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                for (size_t i = 0; i < mTracks.size() ; i++) {
3596fe3156ec6fd9fa57dde913fd8567530d095a6550Jean-Michel Trivi                    int name = getTrackName_l(mTracks[i]->mChannelMask, mTracks[i]->mSessionId);
3597d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten                    if (name < 0) {
3598d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten                        break;
3599d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten                    }
360065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mTracks[i]->mName = name;
360165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    // limit track sample rate to 2 x new output sample rate
360265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    if (mTracks[i]->mCblk->sampleRate > 2 * sampleRate()) {
360365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        mTracks[i]->mCblk->sampleRate = 2 * sampleRate();
360465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    }
360565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
3606896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent                sendIoConfigEvent_l(AudioSystem::OUTPUT_CONFIG_CHANGED);
360765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
360865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
360965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
361065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mNewParameters.removeAt(0);
361165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
361265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mParamStatus = status;
361365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mParamCond.signal();
361460cd0a0d488e604d27fc7dbb02b00348693dfde2Eric Laurent        // wait for condition with time out in case the thread calling ThreadBase::setParameters()
361560cd0a0d488e604d27fc7dbb02b00348693dfde2Eric Laurent        // already timed out waiting for the status and will never signal the condition.
36167dede876998ff56351d495ec3a798c1b131193e8Glenn Kasten        mWaitWorkCV.waitRelative(mLock, kSetParametersTimeoutNs);
361765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
361858912562617941964939a4182cda71eaeb153d4bGlenn Kasten
361958912562617941964939a4182cda71eaeb153d4bGlenn Kasten    if (!(previousCommand & FastMixerState::IDLE)) {
362058912562617941964939a4182cda71eaeb153d4bGlenn Kasten        ALOG_ASSERT(mFastMixer != NULL);
362158912562617941964939a4182cda71eaeb153d4bGlenn Kasten        FastMixerStateQueue *sq = mFastMixer->sq();
362258912562617941964939a4182cda71eaeb153d4bGlenn Kasten        FastMixerState *state = sq->begin();
362358912562617941964939a4182cda71eaeb153d4bGlenn Kasten        ALOG_ASSERT(state->mCommand == FastMixerState::HOT_IDLE);
362458912562617941964939a4182cda71eaeb153d4bGlenn Kasten        state->mCommand = previousCommand;
362558912562617941964939a4182cda71eaeb153d4bGlenn Kasten        sq->end();
362658912562617941964939a4182cda71eaeb153d4bGlenn Kasten        sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);
362758912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
362858912562617941964939a4182cda71eaeb153d4bGlenn Kasten
362965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return reconfig;
363065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
363165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3632d06785bebf7e43d4a011b62a252771373ada910cGlenn Kastenvoid AudioFlinger::dumpTee(int fd, const sp<NBAIO_Source>& source, audio_io_handle_t id)
363365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
3634d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten    NBAIO_Source *teeSource = source.get();
3635fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten    if (teeSource != NULL) {
3636d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        char teeTime[16];
3637fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        struct timeval tv;
3638fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        gettimeofday(&tv, NULL);
3639fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        struct tm tm;
3640fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        localtime_r(&tv.tv_sec, &tm);
3641d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        strftime(teeTime, sizeof(teeTime), "%T", &tm);
3642d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        char teePath[64];
3643d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        sprintf(teePath, "/data/misc/media/%s_%d.wav", teeTime, id);
3644fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        int teeFd = open(teePath, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
3645fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        if (teeFd >= 0) {
3646fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            char wavHeader[44];
3647fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            memcpy(wavHeader,
3648fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                "RIFF\0\0\0\0WAVEfmt \20\0\0\0\1\0\2\0\104\254\0\0\0\0\0\0\4\0\20\0data\0\0\0\0",
3649fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                sizeof(wavHeader));
3650fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            NBAIO_Format format = teeSource->format();
3651fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            unsigned channelCount = Format_channelCount(format);
3652fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            ALOG_ASSERT(channelCount <= FCC_2);
36533b16c766d1ae2cfd8487e8ffb2b23936fc0a8e17Glenn Kasten            uint32_t sampleRate = Format_sampleRate(format);
3654fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            wavHeader[22] = channelCount;       // number of channels
3655fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            wavHeader[24] = sampleRate;         // sample rate
3656fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            wavHeader[25] = sampleRate >> 8;
3657fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            wavHeader[32] = channelCount * 2;   // block alignment
3658fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            write(teeFd, wavHeader, sizeof(wavHeader));
3659fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            size_t total = 0;
3660fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            bool firstRead = true;
3661fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            for (;;) {
3662fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten#define TEE_SINK_READ 1024
3663fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                short buffer[TEE_SINK_READ * FCC_2];
3664fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                size_t count = TEE_SINK_READ;
36652c3b2da3049627264b7c6b449a1622f002210f03John Grossman                ssize_t actual = teeSource->read(buffer, count,
36662c3b2da3049627264b7c6b449a1622f002210f03John Grossman                        AudioBufferProvider::kInvalidPTS);
3667fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                bool wasFirstRead = firstRead;
3668fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                firstRead = false;
3669fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                if (actual <= 0) {
3670fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                    if (actual == (ssize_t) OVERRUN && wasFirstRead) {
3671fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                        continue;
3672fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                    }
3673fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                    break;
3674fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                }
3675a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent                ALOG_ASSERT(actual <= (ssize_t)count);
3676fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                write(teeFd, buffer, actual * channelCount * sizeof(short));
3677fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten                total += actual;
3678fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            }
3679fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            lseek(teeFd, (off_t) 4, SEEK_SET);
3680fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            uint32_t temp = 44 + total * channelCount * sizeof(short) - 8;
3681fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            write(teeFd, &temp, sizeof(temp));
3682fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            lseek(teeFd, (off_t) 40, SEEK_SET);
3683fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            temp =  total * channelCount * sizeof(short);
3684fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            write(teeFd, &temp, sizeof(temp));
3685fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            close(teeFd);
3686fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            fdprintf(fd, "FastMixer tee copied to %s\n", teePath);
3687fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        } else {
3688fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten            fdprintf(fd, "FastMixer unable to create tee %s: \n", strerror(errno));
3689fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten        }
3690fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten    }
3691d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten}
3692d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten
3693d06785bebf7e43d4a011b62a252771373ada910cGlenn Kastenvoid AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16>& args)
3694d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten{
3695d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten    const size_t SIZE = 256;
3696d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten    char buffer[SIZE];
3697d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten    String8 result;
3698d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten
3699d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten    PlaybackThread::dumpInternals(fd, args);
3700d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten
3701d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten    snprintf(buffer, SIZE, "AudioMixer tracks: %08x\n", mAudioMixer->trackNames());
3702d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten    result.append(buffer);
3703d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten    write(fd, result.string(), result.size());
3704d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten
3705d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten    // Make a non-atomic copy of fast mixer dump state so it won't change underneath us
3706d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten    FastMixerDumpState copy = mFastMixerDumpState;
3707d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten    copy.dump(fd);
3708d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten
3709d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten#ifdef STATE_QUEUE_DUMP
3710d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten    // Similar for state queue
3711d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten    StateQueueObserverDump observerCopy = mStateQueueObserverDump;
3712d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten    observerCopy.dump(fd);
3713d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten    StateQueueMutatorDump mutatorCopy = mStateQueueMutatorDump;
3714d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten    mutatorCopy.dump(fd);
3715d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten#endif
3716d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten
3717d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten    // Write the tee output to a .wav file
3718d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten    dumpTee(fd, mTeeSource, mId);
3719fbae5dae5187aca9d974cbe15ec818e9c6f56705Glenn Kasten
3720087dd8e7232e4c009e9121ab7e8c37985522c9adGlenn Kasten#ifdef AUDIO_WATCHDOG
3721c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten    if (mAudioWatchdog != 0) {
3722c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten        // Make a non-atomic copy of audio watchdog dump so it won't change underneath us
3723c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten        AudioWatchdogDump wdCopy = mAudioWatchdogDump;
3724c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten        wdCopy.dump(fd);
3725c15d6657a17d7cef91f800f40d11760e2e7340afGlenn Kasten    }
3726087dd8e7232e4c009e9121ab7e8c37985522c9adGlenn Kasten#endif
372765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
372865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
37290bf65bdde04b8e66c998ff37e2b2afafddddfa33Glenn Kastenuint32_t AudioFlinger::MixerThread::idleSleepTimeUs() const
373065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
373158912562617941964939a4182cda71eaeb153d4bGlenn Kasten    return (uint32_t)(((mNormalFrameCount * 1000) / mSampleRate) * 1000) / 2;
373265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
373365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
37340bf65bdde04b8e66c998ff37e2b2afafddddfa33Glenn Kastenuint32_t AudioFlinger::MixerThread::suspendSleepTimeUs() const
373525cbe0ecd6df8be7e40537c5d85c82f105038479Eric Laurent{
373658912562617941964939a4182cda71eaeb153d4bGlenn Kasten    return (uint32_t)(((mNormalFrameCount * 1000) / mSampleRate) * 1000);
373725cbe0ecd6df8be7e40537c5d85c82f105038479Eric Laurent}
373825cbe0ecd6df8be7e40537c5d85c82f105038479Eric Laurent
373966fcab972e9218d47c58a915f391b2f48a09903aGlenn Kastenvoid AudioFlinger::MixerThread::cacheParameters_l()
374066fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten{
374166fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten    PlaybackThread::cacheParameters_l();
374266fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten
374366fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten    // FIXME: Relaxed timing because of a certain device that can't meet latency
374466fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten    // Should be reduced to 2x after the vendor fixes the driver issue
374566fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten    // increase threshold again due to low power audio mode. The way this warning
374666fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten    // threshold is calculated and its usefulness should be reconsidered anyway.
374758912562617941964939a4182cda71eaeb153d4bGlenn Kasten    maxPeriod = seconds(mNormalFrameCount) / mSampleRate * 15;
374866fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten}
374966fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten
375065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
375172ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn KastenAudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger,
3752bb4350d3b9e9485ae59e084de270f86aecef8066Glenn Kasten        AudioStreamOut* output, audio_io_handle_t id, audio_devices_t device)
375323bb8becff20449a9b1647d5a1a99b14c83f0cceGlenn Kasten    :   PlaybackThread(audioFlinger, output, id, device, DIRECT)
375484afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten        // mLeftVolFloat, mRightVolFloat
375565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
375665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
375765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
375865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::DirectOutputThread::~DirectOutputThread()
375965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
376065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
376165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
37621465f0c3df04c3166155a852a6a5c10069c1fd0aGlenn KastenAudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prepareTracks_l(
37631465f0c3df04c3166155a852a6a5c10069c1fd0aGlenn Kasten    Vector< sp<Track> > *tracksToRemove
3764000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten)
376565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
37661465f0c3df04c3166155a852a6a5c10069c1fd0aGlenn Kasten    sp<Track> trackToRemove;
37671465f0c3df04c3166155a852a6a5c10069c1fd0aGlenn Kasten
3768fec279f5a0bfaa2a42e91ab6dfa0282baeee308bGlenn Kasten    mixer_state mixerStatus = MIXER_IDLE;
376965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3770952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    // find out which tracks need to be processed
3771952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    if (mActiveTracks.size() != 0) {
3772952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        sp<Track> t = mActiveTracks[0].promote();
3773fec279f5a0bfaa2a42e91ab6dfa0282baeee308bGlenn Kasten        // The track died recently
3774d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        if (t == 0) {
3775d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten            return MIXER_IDLE;
3776d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        }
377765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3778952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        Track* const track = t.get();
3779952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        audio_track_cblk_t* cblk = track->cblk();
3780952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3781952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        // The first time a track is added we wait
3782952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        // for all its buffers to be filled before processing it
378367c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent        uint32_t minFrames;
378467c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent        if ((track->sharedBuffer() == 0) && !track->isStopped() && !track->isPausing()) {
378567c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent            minFrames = mNormalFrameCount;
378667c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent        } else {
378767c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent            minFrames = 1;
378867c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent        }
378967c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent        if ((track->framesReady() >= minFrames) && track->isReady() &&
3790952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                !track->isPaused() && !track->isTerminated())
3791952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        {
379226dd66e8ea7a1abf28c33196fc77822f68a718afGlenn Kasten            ALOGVV("track %d u=%08x, s=%08x [OK]", track->name(), cblk->user, cblk->server);
3793952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3794952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            if (track->mFillingUpStatus == Track::FS_FILLED) {
3795952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                track->mFillingUpStatus = Track::FS_ACTIVE;
3796952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                mLeftVolFloat = mRightVolFloat = 0;
3797952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                if (track->mState == TrackBase::RESUMING) {
3798952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    track->mState = TrackBase::ACTIVE;
3799952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                }
3800952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            }
380167c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent
3802952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            // compute volume for this track
3803952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            float left, right;
3804952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            if (track->isMuted() || mMasterMute || track->isPausing() ||
3805952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                mStreamTypes[track->streamType()].mute) {
3806952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                left = right = 0;
3807952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                if (track->isPausing()) {
3808952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    track->setPaused();
380965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
3810952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            } else {
3811952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                float typeVolume = mStreamTypes[track->streamType()].volume;
3812952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                float v = mMasterVolume * typeVolume;
3813952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                uint32_t vlr = cblk->getVolumeLR();
3814952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                float v_clamped = v * (vlr & 0xFFFF);
3815d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten                if (v_clamped > MAX_GAIN) {
3816d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten                    v_clamped = MAX_GAIN;
3817d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten                }
3818952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                left = v_clamped/MAX_GAIN;
3819952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                v_clamped = v * (vlr >> 16);
3820d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten                if (v_clamped > MAX_GAIN) {
3821d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten                    v_clamped = MAX_GAIN;
3822d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten                }
3823952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                right = v_clamped/MAX_GAIN;
382465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
382565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3826952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            if (left != mLeftVolFloat || right != mRightVolFloat) {
3827952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                mLeftVolFloat = left;
3828952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                mRightVolFloat = right;
3829952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3830952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                // Convert volumes from float to 8.24
3831952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                uint32_t vl = (uint32_t)(left * (1 << 24));
3832952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                uint32_t vr = (uint32_t)(right * (1 << 24));
3833952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3834952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                // Delegate volume control to effect in track effect chain if needed
3835952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                // only one effect chain can be present on DirectOutputThread, so if
3836952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                // there is one, the track is connected to it
3837000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten                if (!mEffectChains.isEmpty()) {
3838952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    // Do not ramp volume if volume is controlled by effect
383967c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent                    mEffectChains[0]->setVolume_l(&vl, &vr);
384067c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent                    left = (float)vl / (1 << 24);
384167c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent                    right = (float)vr / (1 << 24);
384265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
384367c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent                mOutput->stream->set_volume(mOutput->stream, left, right);
3844952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            }
3845952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
3846952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            // reset retry count
3847952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            track->mRetryCount = kMaxTrackRetriesDirect;
3848b071e9bc248865ef87a339044c0c5cbabfac175cGlenn Kasten            mActiveTrack = t;
3849fec279f5a0bfaa2a42e91ab6dfa0282baeee308bGlenn Kasten            mixerStatus = MIXER_TRACKS_READY;
3850952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        } else {
385191b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent            // clear effect chain input buffer if an active track underruns to avoid sending
385291b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent            // previous audio buffer again to effects
385391b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent            if (!mEffectChains.isEmpty()) {
385491b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent                mEffectChains[0]->clearInputBuffer();
385591b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent            }
385691b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent
385726dd66e8ea7a1abf28c33196fc77822f68a718afGlenn Kasten            ALOGVV("track %d u=%08x, s=%08x [NOT READY]", track->name(), cblk->user, cblk->server);
3858842c5d9553f3f8e97d04ed1bd0d37e4851240654Glenn Kasten            if ((track->sharedBuffer() != 0) || track->isTerminated() ||
385967c0a58e05f4c19d4a6f01fe6f06267d57b49305Eric Laurent                    track->isStopped() || track->isPaused()) {
3860952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                // We have consumed all the buffers of this track.
3861952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                // Remove it from the list of active tracks.
3862a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                // TODO: implement behavior for compressed audio
3863a045dcafd2b77036210f5b72e79d745ad4c1b848Jean-Michel Trivi                size_t audioHALFrames = (latency_l() * mSampleRate) / 1000;
3864a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                size_t framesWritten =
3865a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                        mBytesWritten / audio_stream_frame_size(&mOutput->stream->common);
3866291f824e02ff517a34cfe50220b4e2b402ee998dGlenn Kasten                if (mStandby || track->presentationComplete(framesWritten, audioHALFrames)) {
38672986460984580833161bdaabc7f17da1005a8961Eric Laurent                    if (track->isStopped()) {
38682986460984580833161bdaabc7f17da1005a8961Eric Laurent                        track->reset();
38692986460984580833161bdaabc7f17da1005a8961Eric Laurent                    }
3870a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                    trackToRemove = track;
3871a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                }
3872952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            } else {
3873952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                // No buffers for this track. Give it a few chances to
3874952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                // fill a buffer, then remove it from active list.
3875842c5d9553f3f8e97d04ed1bd0d37e4851240654Glenn Kasten                if (--(track->mRetryCount) <= 0) {
3876842c5d9553f3f8e97d04ed1bd0d37e4851240654Glenn Kasten                    ALOGV("BUFFER TIMEOUT: remove(%d) from active list", track->name());
3877952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    trackToRemove = track;
3878952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                } else {
3879fec279f5a0bfaa2a42e91ab6dfa0282baeee308bGlenn Kasten                    mixerStatus = MIXER_TRACKS_ENABLED;
388065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
388165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
3882952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        }
3883952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    }
3884952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten
38851465f0c3df04c3166155a852a6a5c10069c1fd0aGlenn Kasten    // FIXME merge this with similar code for removing multiple tracks
3886952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    // remove all the tracks that need to be...
3887952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    if (CC_UNLIKELY(trackToRemove != 0)) {
38881465f0c3df04c3166155a852a6a5c10069c1fd0aGlenn Kasten        tracksToRemove->add(trackToRemove);
3889952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        mActiveTracks.remove(trackToRemove);
3890952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        if (!mEffectChains.isEmpty()) {
38915798d4ebf236357a4b13246f40e52b90a34d09a4Glenn Kasten            ALOGV("stopping track on chain %p for session Id: %d", mEffectChains[0].get(),
3892952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten                    trackToRemove->sessionId());
3893952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            mEffectChains[0]->decActiveTrackCnt();
3894952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        }
3895952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        if (trackToRemove->isTerminated()) {
3896952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            removeTrack_l(trackToRemove);
3897952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        }
3898952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    }
389965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3900fec279f5a0bfaa2a42e91ab6dfa0282baeee308bGlenn Kasten    return mixerStatus;
3901000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten}
390265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3903000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kastenvoid AudioFlinger::DirectOutputThread::threadLoop_mix()
3904000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten{
3905952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    AudioBufferProvider::Buffer buffer;
3906952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    size_t frameCount = mFrameCount;
3907952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    int8_t *curBuf = (int8_t *)mMixBuffer;
3908952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    // output audio to hardware
3909952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    while (frameCount) {
3910952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        buffer.frameCount = frameCount;
3911b071e9bc248865ef87a339044c0c5cbabfac175cGlenn Kasten        mActiveTrack->getNextBuffer(&buffer);
3912952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        if (CC_UNLIKELY(buffer.raw == NULL)) {
3913952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            memset(curBuf, 0, frameCount * mFrameSize);
3914952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            break;
3915952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        }
3916952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        memcpy(curBuf, buffer.raw, buffer.frameCount * mFrameSize);
3917952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        frameCount -= buffer.frameCount;
3918952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        curBuf += buffer.frameCount * mFrameSize;
3919b071e9bc248865ef87a339044c0c5cbabfac175cGlenn Kasten        mActiveTrack->releaseBuffer(&buffer);
3920952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    }
3921952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    sleepTime = 0;
3922952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    standbyTime = systemTime() + standbyDelay;
3923b071e9bc248865ef87a339044c0c5cbabfac175cGlenn Kasten    mActiveTrack.clear();
392473f4bc33e0d458933460250a47c64aa868c05f97Glenn Kasten
3925000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten}
3926000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
3927000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kastenvoid AudioFlinger::DirectOutputThread::threadLoop_sleepTime()
3928000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten{
3929952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    if (sleepTime == 0) {
3930fec279f5a0bfaa2a42e91ab6dfa0282baeee308bGlenn Kasten        if (mMixerStatus == MIXER_TRACKS_ENABLED) {
3931952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            sleepTime = activeSleepTime;
3932952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        } else {
3933952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            sleepTime = idleSleepTime;
3934952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        }
3935952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    } else if (mBytesWritten != 0 && audio_is_linear_pcm(mFormat)) {
393658912562617941964939a4182cda71eaeb153d4bGlenn Kasten        memset(mMixBuffer, 0, mFrameCount * mFrameSize);
3937952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        sleepTime = 0;
3938952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    }
393965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
394065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
394165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// getTrackName_l() must be called with ThreadBase::mLock held
3942fe3156ec6fd9fa57dde913fd8567530d095a6550Jean-Michel Triviint AudioFlinger::DirectOutputThread::getTrackName_l(audio_channel_mask_t channelMask,
3943fe3156ec6fd9fa57dde913fd8567530d095a6550Jean-Michel Trivi        int sessionId)
394465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
394565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return 0;
394665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
394765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
394865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// deleteTrackName_l() must be called with ThreadBase::mLock held
394965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::DirectOutputThread::deleteTrackName_l(int name)
395065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
395165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
395265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
395365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// checkForNewParameters_l() must be called with ThreadBase::mLock held
395465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool AudioFlinger::DirectOutputThread::checkForNewParameters_l()
395565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
395665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool reconfig = false;
395765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
395865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    while (!mNewParameters.isEmpty()) {
395965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status_t status = NO_ERROR;
396065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        String8 keyValuePair = mNewParameters[0];
396165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        AudioParameter param = AudioParameter(keyValuePair);
396265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int value;
396365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
396465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (param.getInt(String8(AudioParameter::keyFrameCount), value) == NO_ERROR) {
396565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // do not accept frame count changes if tracks are open as the track buffer
396665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // size depends on frame count and correct behavior would not be garantied
396765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // if frame count is changed after track creation
396865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (!mTracks.isEmpty()) {
396965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                status = INVALID_OPERATION;
397065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else {
397165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                reconfig = true;
397265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
397365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
397465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (status == NO_ERROR) {
3975799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin            status = mOutput->stream->common.set_parameters(&mOutput->stream->common,
3976fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                                    keyValuePair.string());
397765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (!mStandby && status == INVALID_OPERATION) {
3978e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                mOutput->stream->common.standby(&mOutput->stream->common);
3979e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                mStandby = true;
3980e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                mBytesWritten = 0;
3981e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                status = mOutput->stream->common.set_parameters(&mOutput->stream->common,
3982fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                                       keyValuePair.string());
398365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
398465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (status == NO_ERROR && reconfig) {
398565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                readOutputParameters();
3986896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent                sendIoConfigEvent_l(AudioSystem::OUTPUT_CONFIG_CHANGED);
398765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
398865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
398965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
399065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mNewParameters.removeAt(0);
399165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
399265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mParamStatus = status;
399365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mParamCond.signal();
399460cd0a0d488e604d27fc7dbb02b00348693dfde2Eric Laurent        // wait for condition with time out in case the thread calling ThreadBase::setParameters()
399560cd0a0d488e604d27fc7dbb02b00348693dfde2Eric Laurent        // already timed out waiting for the status and will never signal the condition.
39967dede876998ff56351d495ec3a798c1b131193e8Glenn Kasten        mWaitWorkCV.waitRelative(mLock, kSetParametersTimeoutNs);
399765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
399865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return reconfig;
399965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
400065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
40010bf65bdde04b8e66c998ff37e2b2afafddddfa33Glenn Kastenuint32_t AudioFlinger::DirectOutputThread::activeSleepTimeUs() const
400265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
400365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    uint32_t time;
4004fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (audio_is_linear_pcm(mFormat)) {
4005162b40bbaf3c3a24f61a6636bef6f80a9c0a31ddEric Laurent        time = PlaybackThread::activeSleepTimeUs();
400665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
400765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        time = 10000;
400865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
400965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return time;
401065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
401165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
40120bf65bdde04b8e66c998ff37e2b2afafddddfa33Glenn Kastenuint32_t AudioFlinger::DirectOutputThread::idleSleepTimeUs() const
401365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
401465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    uint32_t time;
4015fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (audio_is_linear_pcm(mFormat)) {
401660e182437228312cc28469a5b0dfde77ac848e1aEric Laurent        time = (uint32_t)(((mFrameCount * 1000) / mSampleRate) * 1000) / 2;
401765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
401865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        time = 10000;
401965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
402065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return time;
402165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
402265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
40230bf65bdde04b8e66c998ff37e2b2afafddddfa33Glenn Kastenuint32_t AudioFlinger::DirectOutputThread::suspendSleepTimeUs() const
402425cbe0ecd6df8be7e40537c5d85c82f105038479Eric Laurent{
402525cbe0ecd6df8be7e40537c5d85c82f105038479Eric Laurent    uint32_t time;
4026fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (audio_is_linear_pcm(mFormat)) {
402725cbe0ecd6df8be7e40537c5d85c82f105038479Eric Laurent        time = (uint32_t)(((mFrameCount * 1000) / mSampleRate) * 1000);
402825cbe0ecd6df8be7e40537c5d85c82f105038479Eric Laurent    } else {
402925cbe0ecd6df8be7e40537c5d85c82f105038479Eric Laurent        time = 10000;
403025cbe0ecd6df8be7e40537c5d85c82f105038479Eric Laurent    }
403125cbe0ecd6df8be7e40537c5d85c82f105038479Eric Laurent    return time;
403225cbe0ecd6df8be7e40537c5d85c82f105038479Eric Laurent}
403325cbe0ecd6df8be7e40537c5d85c82f105038479Eric Laurent
403466fcab972e9218d47c58a915f391b2f48a09903aGlenn Kastenvoid AudioFlinger::DirectOutputThread::cacheParameters_l()
403566fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten{
403666fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten    PlaybackThread::cacheParameters_l();
403766fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten
403866fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten    // use shorter standby delay as on normal output to release
403966fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten    // hardware resources as soon as possible
404066fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten    standbyDelay = microseconds(activeSleepTime*2);
404166fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten}
404225cbe0ecd6df8be7e40537c5d85c82f105038479Eric Laurent
404365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
404465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
404523bb8becff20449a9b1647d5a1a99b14c83f0cceGlenn KastenAudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger,
404672ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten        AudioFlinger::MixerThread* mainThread, audio_io_handle_t id)
404785ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten    :   MixerThread(audioFlinger, mainThread->getOutput(), id, mainThread->outDevice(),
404885ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                DUPLICATING),
404923bb8becff20449a9b1647d5a1a99b14c83f0cceGlenn Kasten        mWaitTimeMs(UINT_MAX)
405065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
405165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    addOutputTrack(mainThread);
405265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
405365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
405465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::DuplicatingThread::~DuplicatingThread()
405565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
405665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < mOutputTracks.size(); i++) {
405765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mOutputTracks[i]->destroy();
405865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
405965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
406065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4061000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kastenvoid AudioFlinger::DuplicatingThread::threadLoop_mix()
406265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
4063952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    // mix buffers...
4064952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    if (outputsReady(outputTracks)) {
4065952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        mAudioMixer->process(AudioBufferProvider::kInvalidPTS);
4066952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    } else {
4067952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        memset(mMixBuffer, 0, mixBufferSize);
4068952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    }
4069952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    sleepTime = 0;
407058912562617941964939a4182cda71eaeb153d4bGlenn Kasten    writeFrames = mNormalFrameCount;
4071a4f7e0e9a0e92a063f1b3a08988cf46e2cf1fa94Eric Laurent    standbyTime = systemTime() + standbyDelay;
4072000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten}
4073000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten
4074000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kastenvoid AudioFlinger::DuplicatingThread::threadLoop_sleepTime()
4075000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten{
4076952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    if (sleepTime == 0) {
4077fec279f5a0bfaa2a42e91ab6dfa0282baeee308bGlenn Kasten        if (mMixerStatus == MIXER_TRACKS_ENABLED) {
4078952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            sleepTime = activeSleepTime;
4079952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        } else {
4080952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten            sleepTime = idleSleepTime;
4081952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        }
4082952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    } else if (mBytesWritten != 0) {
4083a4f7e0e9a0e92a063f1b3a08988cf46e2cf1fa94Eric Laurent        if (mMixerStatus == MIXER_TRACKS_ENABLED) {
4084a4f7e0e9a0e92a063f1b3a08988cf46e2cf1fa94Eric Laurent            writeFrames = mNormalFrameCount;
4085a4f7e0e9a0e92a063f1b3a08988cf46e2cf1fa94Eric Laurent            memset(mMixBuffer, 0, mixBufferSize);
4086a4f7e0e9a0e92a063f1b3a08988cf46e2cf1fa94Eric Laurent        } else {
4087a4f7e0e9a0e92a063f1b3a08988cf46e2cf1fa94Eric Laurent            // flush remaining overflow buffers in output tracks
4088a4f7e0e9a0e92a063f1b3a08988cf46e2cf1fa94Eric Laurent            writeFrames = 0;
4089952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        }
4090a4f7e0e9a0e92a063f1b3a08988cf46e2cf1fa94Eric Laurent        sleepTime = 0;
4091952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    }
4092000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten}
409365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4094000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kastenvoid AudioFlinger::DuplicatingThread::threadLoop_write()
4095000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten{
4096952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    for (size_t i = 0; i < outputTracks.size(); i++) {
4097952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        outputTracks[i]->write(mMixBuffer, writeFrames);
4098952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    }
4099952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    mBytesWritten += mixBufferSize;
4100000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten}
4101688a64030834ea2f52cc9765676ddf6aa34df767Glenn Kasten
4102000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kastenvoid AudioFlinger::DuplicatingThread::threadLoop_standby()
4103000f0e39b4d0c88441297a05ab5f8da6832c1640Glenn Kasten{
4104952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    // DuplicatingThread implements standby by stopping all tracks
4105952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    for (size_t i = 0; i < outputTracks.size(); i++) {
4106952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten        outputTracks[i]->stop();
4107952eeb27682a9b2ddfa761f24b6eb5e18fe5d814Glenn Kasten    }
410865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
410965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4110fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kastenvoid AudioFlinger::DuplicatingThread::saveOutputTracks()
4111fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten{
4112fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten    outputTracks = mOutputTracks;
4113fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten}
4114fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten
4115fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kastenvoid AudioFlinger::DuplicatingThread::clearOutputTracks()
4116fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten{
4117fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten    outputTracks.clear();
4118fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten}
4119fa26a859bacb597587a8f49acfc3127351fa688cGlenn Kasten
412065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::DuplicatingThread::addOutputTrack(MixerThread *thread)
412165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
4122b6b740629c9f11535086e744465bada03f26df11Glenn Kasten    Mutex::Autolock _l(mLock);
412399e53b86eebb605b70dd7591b89bf61a9414ed0eGlenn Kasten    // FIXME explain this formula
4124e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten    size_t frameCount = (3 * mNormalFrameCount * mSampleRate) / thread->sampleRate();
41259eaa55756c5b245970447019250ce852f5189525Glenn Kasten    OutputTrack *outputTrack = new OutputTrack(thread,
412665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                            this,
412765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                            mSampleRate,
412865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                            mFormat,
41290d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi                                            mChannelMask,
413065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                            frameCount);
413165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (outputTrack->cblk() != NULL) {
4132fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        thread->setStreamVolume(AUDIO_STREAM_CNT, 1.0f);
413365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mOutputTracks.add(outputTrack);
41343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("addOutputTrack() track %p, on thread %p", outputTrack, thread);
4135438b036deaf4413503567a75a2861c000d21da5bGlenn Kasten        updateWaitTime_l();
413665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
413765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
413865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
413965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::DuplicatingThread::removeOutputTrack(MixerThread *thread)
414065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
414165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
414265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < mOutputTracks.size(); i++) {
4143a111792f1314479c649d1d44c30c2caf70c00c2aGlenn Kasten        if (mOutputTracks[i]->thread() == thread) {
414465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mOutputTracks[i]->destroy();
414565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mOutputTracks.removeAt(i);
4146438b036deaf4413503567a75a2861c000d21da5bGlenn Kasten            updateWaitTime_l();
414765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return;
414865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
414965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
41503856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("removeOutputTrack(): unkonwn thread: %p", thread);
415165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
415265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4153438b036deaf4413503567a75a2861c000d21da5bGlenn Kasten// caller must hold mLock
4154438b036deaf4413503567a75a2861c000d21da5bGlenn Kastenvoid AudioFlinger::DuplicatingThread::updateWaitTime_l()
415565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
415665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mWaitTimeMs = UINT_MAX;
415765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < mOutputTracks.size(); i++) {
415865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<ThreadBase> strong = mOutputTracks[i]->thread().promote();
41597378ca506e4e20c2b2d4e94a131cf1b95831adb5Glenn Kasten        if (strong != 0) {
416065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            uint32_t waitTimeMs = (strong->frameCount() * 2 * 1000) / strong->sampleRate();
416165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (waitTimeMs < mWaitTimeMs) {
416265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mWaitTimeMs = waitTimeMs;
416365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
416465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
416565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
416665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
416765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
416865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
416985ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kastenbool AudioFlinger::DuplicatingThread::outputsReady(
417085ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten        const SortedVector< sp<OutputTrack> > &outputTracks)
417165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
417265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < outputTracks.size(); i++) {
4173e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        sp<ThreadBase> thread = outputTracks[i]->thread().promote();
417465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (thread == 0) {
417585ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten            ALOGW("DuplicatingThread::outputsReady() could not promote thread on output track %p",
417685ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                    outputTracks[i].get());
417765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return false;
417865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
417965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
418001542f2704f39956da09ae2840e192dab760091fGlenn Kasten        // see note at standby() declaration
418165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (playbackThread->standby() && !playbackThread->isSuspended()) {
418285ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten            ALOGV("DuplicatingThread output track %p on thread %p Not Ready", outputTracks[i].get(),
418385ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                    thread.get());
418465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return false;
418565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
418665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
418765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return true;
418865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
418965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
41900bf65bdde04b8e66c998ff37e2b2afafddddfa33Glenn Kastenuint32_t AudioFlinger::DuplicatingThread::activeSleepTimeUs() const
419165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
419265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return (mWaitTimeMs * 1000) / 2;
419365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
419465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
419566fcab972e9218d47c58a915f391b2f48a09903aGlenn Kastenvoid AudioFlinger::DuplicatingThread::cacheParameters_l()
419666fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten{
419766fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten    // updateWaitTime_l() sets mWaitTimeMs, which affects activeSleepTimeUs(), so call it first
419866fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten    updateWaitTime_l();
419966fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten
420066fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten    MixerThread::cacheParameters_l();
420166fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten}
420266fcab972e9218d47c58a915f391b2f48a09903aGlenn Kasten
420365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
420465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
420565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// TrackBase constructor must be called with AudioFlinger::mLock held
420665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::ThreadBase::TrackBase::TrackBase(
42079eaa55756c5b245970447019250ce852f5189525Glenn Kasten            ThreadBase *thread,
420865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            const sp<Client>& client,
420965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            uint32_t sampleRate,
421058f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten            audio_format_t format,
4211254af180475346b6186b49c297f340c9c4817511Glenn Kasten            audio_channel_mask_t channelMask,
4212e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten            size_t frameCount,
421365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            const sp<IMemory>& sharedBuffer,
421465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            int sessionId)
421565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    :   RefBase(),
421665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mThread(thread),
421765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mClient(client),
421884afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten        mCblk(NULL),
421984afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten        // mBuffer
422084afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten        // mBufferEnd
42219f2016d9adfb4f88fa0bbfcfa5954f79160db595Glenn Kasten        mStepCount(0),
422265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mState(IDLE),
422358912562617941964939a4182cda71eaeb153d4bGlenn Kasten        mSampleRate(sampleRate),
422465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mFormat(format),
422560a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten        mChannelMask(channelMask),
422660a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten        mChannelCount(popcount(channelMask)),
422760a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten        mFrameSize(audio_is_linear_pcm(format) ?
422860a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten                mChannelCount * audio_bytes_per_sample(format) : sizeof(int8_t)),
42295cf034d92d901169ca6e36c90475f40715827fcdGlenn Kasten        mStepServerFailed(false),
423065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mSessionId(sessionId)
423165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
4232287fedb1b1430f138c1f583869b10294773945beGlenn Kasten    // client == 0 implies sharedBuffer == 0
4233287fedb1b1430f138c1f583869b10294773945beGlenn Kasten    ALOG_ASSERT(!(client == 0 && sharedBuffer != 0));
4234287fedb1b1430f138c1f583869b10294773945beGlenn Kasten
423585ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten    ALOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(),
423685ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten            sharedBuffer->size());
423765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4238b8a805261bf0282e992d3608035e47d05a898710Steve Block    // ALOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize);
4239e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    size_t size = sizeof(audio_track_cblk_t);
424060a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten    size_t bufferSize = frameCount * mFrameSize;
4241e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    if (sharedBuffer == 0) {
4242e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        size += bufferSize;
4243e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    }
4244e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten
4245287fedb1b1430f138c1f583869b10294773945beGlenn Kasten    if (client != 0) {
424665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mCblkMemory = client->heap()->allocate(size);
424765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mCblkMemory != 0) {
424865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer());
4249287fedb1b1430f138c1f583869b10294773945beGlenn Kasten            // can't assume mCblk != NULL
425065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
425129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("not enough memory for AudioTrack size=%u", size);
425265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            client->heap()->dump("AudioTrack");
425365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return;
425465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
4255e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    } else {
4256e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        mCblk = (audio_track_cblk_t *)(new uint8_t[size]);
4257287fedb1b1430f138c1f583869b10294773945beGlenn Kasten        // assume mCblk != NULL
4258287fedb1b1430f138c1f583869b10294773945beGlenn Kasten    }
4259287fedb1b1430f138c1f583869b10294773945beGlenn Kasten
4260287fedb1b1430f138c1f583869b10294773945beGlenn Kasten    // construct the shared structure in-place.
4261287fedb1b1430f138c1f583869b10294773945beGlenn Kasten    if (mCblk != NULL) {
4262ea7939a079b3600cab955760839b021326f8cfc3Glenn Kasten        new(mCblk) audio_track_cblk_t();
4263ea7939a079b3600cab955760839b021326f8cfc3Glenn Kasten        // clear all buffers
4264ea7939a079b3600cab955760839b021326f8cfc3Glenn Kasten        mCblk->frameCount = frameCount;
4265ea7939a079b3600cab955760839b021326f8cfc3Glenn Kasten        mCblk->sampleRate = sampleRate;
4266a1472d9883e35edd280201c8be3191695007dfd4Marco Nelissen// uncomment the following lines to quickly test 32-bit wraparound
4267287fedb1b1430f138c1f583869b10294773945beGlenn Kasten//      mCblk->user = 0xffff0000;
4268287fedb1b1430f138c1f583869b10294773945beGlenn Kasten//      mCblk->server = 0xffff0000;
4269287fedb1b1430f138c1f583869b10294773945beGlenn Kasten//      mCblk->userBase = 0xffff0000;
4270287fedb1b1430f138c1f583869b10294773945beGlenn Kasten//      mCblk->serverBase = 0xffff0000;
4271287fedb1b1430f138c1f583869b10294773945beGlenn Kasten        if (sharedBuffer == 0) {
4272287fedb1b1430f138c1f583869b10294773945beGlenn Kasten            mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
427360a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten            memset(mBuffer, 0, bufferSize);
4274287fedb1b1430f138c1f583869b10294773945beGlenn Kasten            // Force underrun condition to avoid false underrun callback until first data is
4275287fedb1b1430f138c1f583869b10294773945beGlenn Kasten            // written to buffer (other flags are cleared)
4276287fedb1b1430f138c1f583869b10294773945beGlenn Kasten            mCblk->flags = CBLK_UNDERRUN;
4277287fedb1b1430f138c1f583869b10294773945beGlenn Kasten        } else {
4278287fedb1b1430f138c1f583869b10294773945beGlenn Kasten            mBuffer = sharedBuffer->pointer();
4279287fedb1b1430f138c1f583869b10294773945beGlenn Kasten        }
4280ea7939a079b3600cab955760839b021326f8cfc3Glenn Kasten        mBufferEnd = (uint8_t *)mBuffer + bufferSize;
4281e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    }
428265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
428365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
428465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::ThreadBase::TrackBase::~TrackBase()
428565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
4286a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten    if (mCblk != NULL) {
42871a0ae5be3d1273cba12584b33830d859510fbf82Glenn Kasten        if (mClient == 0) {
428865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            delete mCblk;
42891a0ae5be3d1273cba12584b33830d859510fbf82Glenn Kasten        } else {
42901a0ae5be3d1273cba12584b33830d859510fbf82Glenn Kasten            mCblk->~audio_track_cblk_t();   // destroy our shared-structure.
429165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
429265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
4293dbfafaffe2e97eaf8d74ec6b6c468418a1ad2443Glenn Kasten    mCblkMemory.clear();    // free the shared memory before releasing the heap it belongs to
42947378ca506e4e20c2b2d4e94a131cf1b95831adb5Glenn Kasten    if (mClient != 0) {
429584afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten        // Client destructor must run with AudioFlinger mutex locked
429665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock _l(mClient->audioFlinger()->mLock);
42977378ca506e4e20c2b2d4e94a131cf1b95831adb5Glenn Kasten        // If the client's reference count drops to zero, the associated destructor
42987378ca506e4e20c2b2d4e94a131cf1b95831adb5Glenn Kasten        // must run with AudioFlinger lock held. Thus the explicit clear() rather than
42997378ca506e4e20c2b2d4e94a131cf1b95831adb5Glenn Kasten        // relying on the automatic clear() at end of scope.
430065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mClient.clear();
430165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
430265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
430365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
430401c4ebf6b794493898114a502ed36de13137f7e5Glenn Kasten// AudioBufferProvider interface
430501c4ebf6b794493898114a502ed36de13137f7e5Glenn Kasten// getNextBuffer() = 0;
430601c4ebf6b794493898114a502ed36de13137f7e5Glenn Kasten// This implementation of releaseBuffer() is used by Track and RecordTrack, but not TimedTrack
430765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::ThreadBase::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
430865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
4309e0feee3da22beeffbd9357540e265f13b2119cbbGlenn Kasten    buffer->raw = NULL;
43109f2016d9adfb4f88fa0bbfcfa5954f79160db595Glenn Kasten    mStepCount = buffer->frameCount;
4311288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    // FIXME See note at getNextBuffer()
431201c4ebf6b794493898114a502ed36de13137f7e5Glenn Kasten    (void) step();      // ignore return value of step()
431365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    buffer->frameCount = 0;
431465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
431565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
431665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool AudioFlinger::ThreadBase::TrackBase::step() {
431765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool result;
431865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    audio_track_cblk_t* cblk = this->cblk();
431965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
43209f2016d9adfb4f88fa0bbfcfa5954f79160db595Glenn Kasten    result = cblk->stepServer(mStepCount, isOut());
432165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!result) {
43223856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("stepServer failed acquiring cblk mutex");
43235cf034d92d901169ca6e36c90475f40715827fcdGlenn Kasten        mStepServerFailed = true;
432465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
432565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return result;
432665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
432765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
432865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::ThreadBase::TrackBase::reset() {
432965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    audio_track_cblk_t* cblk = this->cblk();
433065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
433165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    cblk->user = 0;
433265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    cblk->server = 0;
433365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    cblk->userBase = 0;
433465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    cblk->serverBase = 0;
43355cf034d92d901169ca6e36c90475f40715827fcdGlenn Kasten    mStepServerFailed = false;
43363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("TrackBase::reset");
433765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
433865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
43393b16c766d1ae2cfd8487e8ffb2b23936fc0a8e17Glenn Kastenuint32_t AudioFlinger::ThreadBase::TrackBase::sampleRate() const {
43403b16c766d1ae2cfd8487e8ffb2b23936fc0a8e17Glenn Kasten    return mCblk->sampleRate;
434165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
434265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
434365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid* AudioFlinger::ThreadBase::TrackBase::getBuffer(uint32_t offset, uint32_t frames) const {
434465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    audio_track_cblk_t* cblk = this->cblk();
434560a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten    int8_t *bufferStart = (int8_t *)mBuffer + (offset-cblk->serverBase) * mFrameSize;
434660a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten    int8_t *bufferEnd = bufferStart + frames * mFrameSize;
434765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
434865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // Check validity of returned pointer in case the track control block would have been corrupted.
4349acb86cccbd9d245439a04cef0bcefa589addaa4cJean-Michel Trivi    ALOG_ASSERT(!(bufferStart < mBuffer || bufferStart > bufferEnd || bufferEnd > mBufferEnd),
4350acb86cccbd9d245439a04cef0bcefa589addaa4cJean-Michel Trivi            "TrackBase::getBuffer buffer out of range:\n"
4351acb86cccbd9d245439a04cef0bcefa589addaa4cJean-Michel Trivi                "    start: %p, end %p , mBuffer %p mBufferEnd %p\n"
435260a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten                "    server %u, serverBase %u, user %u, userBase %u, frameSize %u",
435365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                bufferStart, bufferEnd, mBuffer, mBufferEnd,
435460a839204713e0f8258d082af83262b1eb33a6c3Glenn Kasten                cblk->server, cblk->serverBase, cblk->user, cblk->userBase, mFrameSize);
435565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
435665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return bufferStart;
435765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
435865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4359a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurentstatus_t AudioFlinger::ThreadBase::TrackBase::setSyncEvent(const sp<SyncEvent>& event)
4360a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent{
4361a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    mSyncEvents.add(event);
4362a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    return NO_ERROR;
4363a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent}
4364a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
436565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
436665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
436765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Track constructor must be called with AudioFlinger::mLock and ThreadBase::mLock held
436865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::PlaybackThread::Track::Track(
43699eaa55756c5b245970447019250ce852f5189525Glenn Kasten            PlaybackThread *thread,
437065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            const sp<Client>& client,
4371fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten            audio_stream_type_t streamType,
437265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            uint32_t sampleRate,
437358f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten            audio_format_t format,
4374254af180475346b6186b49c297f340c9c4817511Glenn Kasten            audio_channel_mask_t channelMask,
4375e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten            size_t frameCount,
437665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            const sp<IMemory>& sharedBuffer,
437773d227557ba5192735356bacab9f77b44980793bGlenn Kasten            int sessionId,
437873d227557ba5192735356bacab9f77b44980793bGlenn Kasten            IAudioFlinger::track_flags_t flags)
437985ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten    :   TrackBase(thread, client, sampleRate, format, channelMask, frameCount, sharedBuffer,
438085ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten            sessionId),
4381f99590187e2e3f1cf6f093063170edec269cac5dGlenn Kasten    mMute(false),
438258912562617941964939a4182cda71eaeb153d4bGlenn Kasten    mFillingUpStatus(FS_INVALID),
4383f99590187e2e3f1cf6f093063170edec269cac5dGlenn Kasten    // mRetryCount initialized later when needed
4384f99590187e2e3f1cf6f093063170edec269cac5dGlenn Kasten    mSharedBuffer(sharedBuffer),
4385f99590187e2e3f1cf6f093063170edec269cac5dGlenn Kasten    mStreamType(streamType),
4386f99590187e2e3f1cf6f093063170edec269cac5dGlenn Kasten    mName(-1),  // see note below
4387f99590187e2e3f1cf6f093063170edec269cac5dGlenn Kasten    mMainBuffer(thread->mixBuffer()),
4388f99590187e2e3f1cf6f093063170edec269cac5dGlenn Kasten    mAuxBuffer(NULL),
4389a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    mAuxEffectId(0), mHasVolumeController(false),
439073d227557ba5192735356bacab9f77b44980793bGlenn Kasten    mPresentationCompleteFrames(0),
439158912562617941964939a4182cda71eaeb153d4bGlenn Kasten    mFlags(flags),
439258912562617941964939a4182cda71eaeb153d4bGlenn Kasten    mFastIndex(-1),
4393288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    mUnderrunCount(0),
439458912562617941964939a4182cda71eaeb153d4bGlenn Kasten    mCachedVolume(1.0)
439565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
439665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mCblk != NULL) {
4397893a05479c96f911d02beb0443da3ed6508143a7Glenn Kasten        // to avoid leaking a track name, do not allocate one unless there is an mCblk
4398fe3156ec6fd9fa57dde913fd8567530d095a6550Jean-Michel Trivi        mName = thread->getTrackName_l(channelMask, sessionId);
43990c9d26d187017f7fb028ab52a0fbc6395142faa4Glenn Kasten        mCblk->mName = mName;
4400893a05479c96f911d02beb0443da3ed6508143a7Glenn Kasten        if (mName < 0) {
4401893a05479c96f911d02beb0443da3ed6508143a7Glenn Kasten            ALOGE("no more track names available");
4402893a05479c96f911d02beb0443da3ed6508143a7Glenn Kasten            return;
4403893a05479c96f911d02beb0443da3ed6508143a7Glenn Kasten        }
4404893a05479c96f911d02beb0443da3ed6508143a7Glenn Kasten        // only allocate a fast track index if we were able to allocate a normal track name
440558912562617941964939a4182cda71eaeb153d4bGlenn Kasten        if (flags & IAudioFlinger::TRACK_FAST) {
440658912562617941964939a4182cda71eaeb153d4bGlenn Kasten            ALOG_ASSERT(thread->mFastTrackAvailMask != 0);
440758912562617941964939a4182cda71eaeb153d4bGlenn Kasten            int i = __builtin_ctz(thread->mFastTrackAvailMask);
44082986460984580833161bdaabc7f17da1005a8961Eric Laurent            ALOG_ASSERT(0 < i && i < (int)FastMixerState::kMaxFastTracks);
4409288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            // FIXME This is too eager.  We allocate a fast track index before the
4410288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            //       fast track becomes active.  Since fast tracks are a scarce resource,
4411288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            //       this means we are potentially denying other more important fast tracks from
4412288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            //       being created.  It would be better to allocate the index dynamically.
441358912562617941964939a4182cda71eaeb153d4bGlenn Kasten            mFastIndex = i;
44140c9d26d187017f7fb028ab52a0fbc6395142faa4Glenn Kasten            mCblk->mName = i;
4415288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            // Read the initial underruns because this field is never cleared by the fast mixer
441609474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten            mObservedUnderruns = thread->getFastTrackUnderruns(i);
441758912562617941964939a4182cda71eaeb153d4bGlenn Kasten            thread->mFastTrackAvailMask &= ~(1 << i);
441858912562617941964939a4182cda71eaeb153d4bGlenn Kasten        }
441965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
442085ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten    ALOGV("Track constructor name %d, calling pid %d", mName,
442185ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten            IPCThreadState::self()->getCallingPid());
442265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
442365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
442465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::PlaybackThread::Track::~Track()
442565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
44263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("PlaybackThread::Track destructor");
442765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
442865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
442965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::PlaybackThread::Track::destroy()
443065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
443165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // NOTE: destroyTrack_l() can remove a strong reference to this Track
443265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // by removing it from mTracks vector, so there is a risk that this Tracks's
443399e53b86eebb605b70dd7591b89bf61a9414ed0eGlenn Kasten    // destructor is called. As the destructor needs to lock mLock,
443465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // we must acquire a strong reference on this Track before locking mLock
443565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // here so that the destructor is called only when exiting this function.
443665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // On the other hand, as long as Track::destroy() is only called by
443765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // TrackHandle destructor, the TrackHandle still holds a strong ref on
443865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // this Track with its member mTrack.
443965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<Track> keep(this);
444065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    { // scope for mLock
444165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<ThreadBase> thread = mThread.promote();
444265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (thread != 0) {
444365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (!isOutputTrack()) {
444465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (mState == ACTIVE || mState == RESUMING) {
444502bbd20cece1785c223ac4ca2ddc635931a80673Glenn Kasten                    AudioSystem::stopOutput(thread->id(), mStreamType, mSessionId);
44469ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
4447d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten#ifdef ADD_BATTERY_DATA
44489ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                    // to track the speaker usage
44499ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                    addBatteryData(IMediaPlayerService::kBatteryDataAudioFlingerStop);
4450d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten#endif
445165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
445265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                AudioSystem::releaseOutput(thread->id());
445365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
445465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            Mutex::Autolock _l(thread->mLock);
445565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
445665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            playbackThread->destroyTrack_l(this);
445765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
445865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
445965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
446065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4461288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten/*static*/ void AudioFlinger::PlaybackThread::Track::appendDumpHeader(String8& result)
4462288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten{
44639f2016d9adfb4f88fa0bbfcfa5954f79160db595Glenn Kasten    result.append("   Name Client Type Fmt Chn mask   Session StpCnt fCount S M F SRate  "
446485ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                  "L dB  R dB    Server      User     Main buf    Aux Buf  Flags Underruns\n");
4465288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten}
4466288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten
446765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size)
446865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
446983d86538c4c479a9225c75ab27938e8f05abb9c8Glenn Kasten    uint32_t vlr = mCblk->getVolumeLR();
447058912562617941964939a4182cda71eaeb153d4bGlenn Kasten    if (isFastTrack()) {
4471288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        sprintf(buffer, "   F %2d", mFastIndex);
447258912562617941964939a4182cda71eaeb153d4bGlenn Kasten    } else {
447358912562617941964939a4182cda71eaeb153d4bGlenn Kasten        sprintf(buffer, "   %4d", mName - AudioMixer::TRACK0);
447458912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
4475288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    track_state state = mState;
4476288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    char stateChar;
4477288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    switch (state) {
4478288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    case IDLE:
4479288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        stateChar = 'I';
4480288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        break;
4481288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    case TERMINATED:
4482288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        stateChar = 'T';
4483288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        break;
4484d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten    case STOPPING_1:
4485d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        stateChar = 's';
4486d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        break;
4487d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten    case STOPPING_2:
4488d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        stateChar = '5';
4489d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        break;
4490288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    case STOPPED:
4491288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        stateChar = 'S';
4492288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        break;
4493288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    case RESUMING:
4494288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        stateChar = 'R';
4495288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        break;
4496288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    case ACTIVE:
4497288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        stateChar = 'A';
4498288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        break;
4499288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    case PAUSING:
4500288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        stateChar = 'p';
4501288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        break;
4502288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    case PAUSED:
4503288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        stateChar = 'P';
4504288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        break;
45052986460984580833161bdaabc7f17da1005a8961Eric Laurent    case FLUSHED:
45062986460984580833161bdaabc7f17da1005a8961Eric Laurent        stateChar = 'F';
45072986460984580833161bdaabc7f17da1005a8961Eric Laurent        break;
4508288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    default:
4509288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        stateChar = '?';
4510288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        break;
4511288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    }
451209474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten    char nowInUnderrun;
451309474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten    switch (mObservedUnderruns.mBitFields.mMostRecent) {
451409474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten    case UNDERRUN_FULL:
451509474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten        nowInUnderrun = ' ';
451609474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten        break;
451709474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten    case UNDERRUN_PARTIAL:
451809474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten        nowInUnderrun = '<';
451909474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten        break;
452009474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten    case UNDERRUN_EMPTY:
452109474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten        nowInUnderrun = '*';
452209474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten        break;
452309474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten    default:
452409474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten        nowInUnderrun = '?';
452509474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten        break;
452609474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten    }
4527e213c86d36414a8fc75e37c52999522fe09c7328Glenn Kasten    snprintf(&buffer[7], size-7, " %6d %4u %3u 0x%08x %7u %6u %6u %1c %1d %1d %5u %5.2g %5.2g  "
4528e213c86d36414a8fc75e37c52999522fe09c7328Glenn Kasten            "0x%08x 0x%08x 0x%08x 0x%08x %#5x %9u%c\n",
452944deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten            (mClient == 0) ? getpid_cached : mClient->pid(),
453065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mStreamType,
453165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mFormat,
45320d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi            mChannelMask,
453365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mSessionId,
45349f2016d9adfb4f88fa0bbfcfa5954f79160db595Glenn Kasten            mStepCount,
4535e213c86d36414a8fc75e37c52999522fe09c7328Glenn Kasten            mCblk->frameCount,
4536288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            stateChar,
453765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mMute,
453865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mFillingUpStatus,
453965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mCblk->sampleRate,
454058912562617941964939a4182cda71eaeb153d4bGlenn Kasten            20.0 * log10((vlr & 0xFFFF) / 4096.0),
454158912562617941964939a4182cda71eaeb153d4bGlenn Kasten            20.0 * log10((vlr >> 16) / 4096.0),
454265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mCblk->server,
454365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mCblk->user,
454465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            (int)mMainBuffer,
4545288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            (int)mAuxBuffer,
4546e213c86d36414a8fc75e37c52999522fe09c7328Glenn Kasten            mCblk->flags,
4547288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten            mUnderrunCount,
454809474df67278c0cd621b57c4aef1deaec4d8447fGlenn Kasten            nowInUnderrun);
454965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
455065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
455101c4ebf6b794493898114a502ed36de13137f7e5Glenn Kasten// AudioBufferProvider interface
45524ff14bae91075eb274eb1c2975982358946e7e63John Grossmanstatus_t AudioFlinger::PlaybackThread::Track::getNextBuffer(
4553e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        AudioBufferProvider::Buffer* buffer, int64_t pts)
455465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
4555e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    audio_track_cblk_t* cblk = this->cblk();
4556e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    uint32_t framesReady;
4557e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    uint32_t framesReq = buffer->frameCount;
455865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4559e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    // Check if last stepServer failed, try to step now
4560e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    if (mStepServerFailed) {
4561288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        // FIXME When called by fast mixer, this takes a mutex with tryLock().
4562288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        //       Since the fast mixer is higher priority than client callback thread,
4563288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        //       it does not result in priority inversion for client.
4564288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        //       But a non-blocking solution would be preferable to avoid
4565288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        //       fast mixer being unable to tryLock(), and
4566288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        //       to avoid the extra context switches if the client wakes up,
4567288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten        //       discovers the mutex is locked, then has to wait for fast mixer to unlock.
4568e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        if (!step())  goto getNextBuffer_exit;
4569e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        ALOGV("stepServer recovered");
4570e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        mStepServerFailed = false;
4571e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    }
457265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4573288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten    // FIXME Same as above
4574864585df53eb97c31e77b3ad7c0d89e4f9b42588Glenn Kasten    framesReady = cblk->framesReadyOut();
457565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4576e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    if (CC_LIKELY(framesReady)) {
457765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        uint32_t s = cblk->server;
457865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        uint32_t bufferEnd = cblk->serverBase + cblk->frameCount;
457965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
458065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        bufferEnd = (cblk->loopEnd < bufferEnd) ? cblk->loopEnd : bufferEnd;
458165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (framesReq > framesReady) {
458265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            framesReq = framesReady;
458365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
4584a1472d9883e35edd280201c8be3191695007dfd4Marco Nelissen        if (framesReq > bufferEnd - s) {
458565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            framesReq = bufferEnd - s;
458665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
458765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4588e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        buffer->raw = getBuffer(s, framesReq);
4589e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        buffer->frameCount = framesReq;
459065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NO_ERROR;
4591e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    }
459265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
459365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopiangetNextBuffer_exit:
4594e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    buffer->raw = NULL;
4595e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    buffer->frameCount = 0;
4596e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    ALOGV("getNextBuffer() no more data for track %d on thread %p", mName, mThread.unsafe_get());
4597e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    return NOT_ENOUGH_DATA;
459865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
459965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4600288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten// Note that framesReady() takes a mutex on the control block using tryLock().
4601288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten// This could result in priority inversion if framesReady() is called by the normal mixer,
4602288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten// as the normal mixer thread runs at lower
4603288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten// priority than the client's callback thread:  there is a short window within framesReady()
4604288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten// during which the normal mixer could be preempted, and the client callback would block.
4605288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten// Another problem can occur if framesReady() is called by the fast mixer:
4606288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten// the tryLock() could block for up to 1 ms, and a sequence of these could delay fast mixer.
4607288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten// FIXME Replace AudioTrackShared control block implementation by a non-blocking FIFO queue.
4608288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kastensize_t AudioFlinger::PlaybackThread::Track::framesReady() const {
4609864585df53eb97c31e77b3ad7c0d89e4f9b42588Glenn Kasten    return mCblk->framesReadyOut();
46104ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
46114ff14bae91075eb274eb1c2975982358946e7e63John Grossman
4612288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kasten// Don't call for fast tracks; the framesReady() could result in priority inversion
461365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool AudioFlinger::PlaybackThread::Track::isReady() const {
4614d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten    if (mFillingUpStatus != FS_FILLING || isStopped() || isPausing()) {
4615d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        return true;
4616d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten    }
461765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
46184ff14bae91075eb274eb1c2975982358946e7e63John Grossman    if (framesReady() >= mCblk->frameCount ||
46199c5fdd83f9b9f49be35107971feb33528d60b945Glenn Kasten            (mCblk->flags & CBLK_FORCEREADY)) {
462065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mFillingUpStatus = FS_FILLED;
46219c5fdd83f9b9f49be35107971feb33528d60b945Glenn Kasten        android_atomic_and(~CBLK_FORCEREADY, &mCblk->flags);
462265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return true;
462365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
462465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return false;
462565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
462665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
46273acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kastenstatus_t AudioFlinger::PlaybackThread::Track::start(AudioSystem::sync_event_t event,
4628a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                                                    int triggerSession)
462965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
463065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t status = NO_ERROR;
463158912562617941964939a4182cda71eaeb153d4bGlenn Kasten    ALOGV("start(%d), calling pid %d session %d",
463258912562617941964939a4182cda71eaeb153d4bGlenn Kasten            mName, IPCThreadState::self()->getCallingPid(), mSessionId);
46333acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten
463465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<ThreadBase> thread = mThread.promote();
463565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread != 0) {
463665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock _l(thread->mLock);
4637b853e986caf43408ad95b9014f194aadff385e3cGlenn Kasten        track_state state = mState;
463865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // here the track could be either new, or restarted
463965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // in both cases "unstop" the track
464065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mState == PAUSED) {
464165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mState = TrackBase::RESUMING;
46423856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("PAUSED => RESUMING (%d) on thread %p", mName, this);
464365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
464465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mState = TrackBase::ACTIVE;
46453856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("? => ACTIVE (%d) on thread %p", mName, this);
464665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
464765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
464865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!isOutputTrack() && state != ACTIVE && state != RESUMING) {
464965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            thread->mLock.unlock();
465002bbd20cece1785c223ac4ca2ddc635931a80673Glenn Kasten            status = AudioSystem::startOutput(thread->id(), mStreamType, mSessionId);
465165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            thread->mLock.lock();
46529ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
4653d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten#ifdef ADD_BATTERY_DATA
46549ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang            // to track the speaker usage
46559ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang            if (status == NO_ERROR) {
46569ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                addBatteryData(IMediaPlayerService::kBatteryDataAudioFlingerStart);
46579ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang            }
4658d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten#endif
465965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
466065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (status == NO_ERROR) {
466165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
466265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            playbackThread->addTrack_l(this);
466365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
466465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mState = state;
46652986460984580833161bdaabc7f17da1005a8961Eric Laurent            triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE);
466665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
466765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
466865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status = BAD_VALUE;
466965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
467065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return status;
467165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
467265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
467365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::PlaybackThread::Track::stop()
467465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
467523d82a9bc9a43b49ba684ba40875b91db310d3b9Glenn Kasten    ALOGV("stop(%d), calling pid %d", mName, IPCThreadState::self()->getCallingPid());
467665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<ThreadBase> thread = mThread.promote();
467765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread != 0) {
467865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock _l(thread->mLock);
4679b853e986caf43408ad95b9014f194aadff385e3cGlenn Kasten        track_state state = mState;
4680d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        if (state == RESUMING || state == ACTIVE || state == PAUSING || state == PAUSED) {
468165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // If the track is not active (PAUSED and buffers full), flush buffers
468265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
468365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (playbackThread->mActiveTracks.indexOf(this) < 0) {
468465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                reset();
4685d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                mState = STOPPED;
4686d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten            } else if (!isFastTrack()) {
4687d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                mState = STOPPED;
4688d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten            } else {
4689d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                // prepareTracks_l() will set state to STOPPING_2 after next underrun,
4690d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                // and then to STOPPED and reset() when presentation is complete
4691d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten                mState = STOPPING_1;
469265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
469385ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten            ALOGV("not stopping/stopped => stopping/stopped (%d) on thread %p", mName,
469485ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                    playbackThread);
469565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
469665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!isOutputTrack() && (state == ACTIVE || state == RESUMING)) {
469765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            thread->mLock.unlock();
469802bbd20cece1785c223ac4ca2ddc635931a80673Glenn Kasten            AudioSystem::stopOutput(thread->id(), mStreamType, mSessionId);
469965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            thread->mLock.lock();
47009ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
4701d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten#ifdef ADD_BATTERY_DATA
47029ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang            // to track the speaker usage
47039ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang            addBatteryData(IMediaPlayerService::kBatteryDataAudioFlingerStop);
4704d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten#endif
470565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
470665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
470765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
470865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
470965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::PlaybackThread::Track::pause()
471065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
471123d82a9bc9a43b49ba684ba40875b91db310d3b9Glenn Kasten    ALOGV("pause(%d), calling pid %d", mName, IPCThreadState::self()->getCallingPid());
471265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<ThreadBase> thread = mThread.promote();
471365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread != 0) {
471465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock _l(thread->mLock);
471565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mState == ACTIVE || mState == RESUMING) {
471665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mState = PAUSING;
47173856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("ACTIVE/RESUMING => PAUSING (%d) on thread %p", mName, thread.get());
471865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (!isOutputTrack()) {
471965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                thread->mLock.unlock();
472002bbd20cece1785c223ac4ca2ddc635931a80673Glenn Kasten                AudioSystem::stopOutput(thread->id(), mStreamType, mSessionId);
472165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                thread->mLock.lock();
47229ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
4723d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten#ifdef ADD_BATTERY_DATA
47249ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                // to track the speaker usage
47259ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                addBatteryData(IMediaPlayerService::kBatteryDataAudioFlingerStop);
4726d3cee2f0f649c01e1153d593cbe723887b8e0ba0Glenn Kasten#endif
472765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
472865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
472965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
473065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
473165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
473265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::PlaybackThread::Track::flush()
473365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
47343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("flush(%d)", mName);
473565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<ThreadBase> thread = mThread.promote();
473665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread != 0) {
473765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock _l(thread->mLock);
4738d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        if (mState != STOPPING_1 && mState != STOPPING_2 && mState != STOPPED && mState != PAUSED &&
47394bd7e5436f9c308503d72e80804fb5637fda1584Glenn Kasten                mState != PAUSING && mState != IDLE && mState != FLUSHED) {
474065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return;
474165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
474265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // No point remaining in PAUSED state after a flush => go to
47432986460984580833161bdaabc7f17da1005a8961Eric Laurent        // FLUSHED state
47442986460984580833161bdaabc7f17da1005a8961Eric Laurent        mState = FLUSHED;
474538ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        // do not reset the track if it is still in the process of being stopped or paused.
474638ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        // this will be done by prepareTracks_l() when the track is stopped.
47472986460984580833161bdaabc7f17da1005a8961Eric Laurent        // prepareTracks_l() will see mState == FLUSHED, then
4748d08f48c2ad2941d62b313007955c7145075d562cGlenn Kasten        // remove from active track list, reset(), and trigger presentation complete
474938ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
475038ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        if (playbackThread->mActiveTracks.indexOf(this) < 0) {
475138ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent            reset();
475238ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        }
475365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
475465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
475565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
475665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::PlaybackThread::Track::reset()
475765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
475865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // Do not reset twice to avoid discarding data written just after a flush and before
475965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // the audioflinger thread detects the track is stopped.
476065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!mResetDone) {
476165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        TrackBase::reset();
476265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Force underrun condition to avoid false underrun callback until first data is
476365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // written to buffer
47649c5fdd83f9b9f49be35107971feb33528d60b945Glenn Kasten        android_atomic_and(~CBLK_FORCEREADY, &mCblk->flags);
47659c5fdd83f9b9f49be35107971feb33528d60b945Glenn Kasten        android_atomic_or(CBLK_UNDERRUN, &mCblk->flags);
476665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mFillingUpStatus = FS_FILLING;
476765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mResetDone = true;
47682986460984580833161bdaabc7f17da1005a8961Eric Laurent        if (mState == FLUSHED) {
47692986460984580833161bdaabc7f17da1005a8961Eric Laurent            mState = IDLE;
47702986460984580833161bdaabc7f17da1005a8961Eric Laurent        }
477165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
477265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
477365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
477465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::PlaybackThread::Track::mute(bool muted)
477565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
477665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mMute = muted;
477765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
477865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
477965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::PlaybackThread::Track::attachAuxEffect(int EffectId)
478065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
478165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t status = DEAD_OBJECT;
478265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<ThreadBase> thread = mThread.promote();
478365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread != 0) {
4784e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
4785717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent        sp<AudioFlinger> af = mClient->audioFlinger();
4786717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent
4787717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent        Mutex::Autolock _l(af->mLock);
4788717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent
4789717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent        sp<PlaybackThread> srcThread = af->getEffectThread_l(AUDIO_SESSION_OUTPUT_MIX, EffectId);
4790717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent
4791109347d421413303eb1678dd9e2aa9d40acf89d2Eric Laurent        if (EffectId != 0 && srcThread != 0 && playbackThread != srcThread.get()) {
4792717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent            Mutex::Autolock _dl(playbackThread->mLock);
4793717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent            Mutex::Autolock _sl(srcThread->mLock);
4794717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent            sp<EffectChain> chain = srcThread->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX);
4795717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent            if (chain == 0) {
4796717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent                return INVALID_OPERATION;
4797717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent            }
4798717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent
4799717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent            sp<EffectModule> effect = chain->getEffectFromId_l(EffectId);
4800717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent            if (effect == 0) {
4801717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent                return INVALID_OPERATION;
4802717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent            }
4803717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent            srcThread->removeEffect_l(effect);
4804717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent            playbackThread->addEffect_l(effect);
4805717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent            // removeEffect_l() has stopped the effect if it was active so it must be restarted
4806717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent            if (effect->state() == EffectModule::ACTIVE ||
4807717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent                    effect->state() == EffectModule::STOPPING) {
4808717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent                effect->start();
4809717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent            }
4810717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent
4811717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent            sp<EffectChain> dstChain = effect->chain().promote();
4812717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent            if (dstChain == 0) {
4813717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent                srcThread->addEffect_l(effect);
4814717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent                return INVALID_OPERATION;
4815717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent            }
4816717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent            AudioSystem::unregisterEffect(effect->id());
4817717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent            AudioSystem::registerEffect(&effect->desc(),
4818717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent                                        srcThread->id(),
4819717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent                                        dstChain->strategy(),
4820717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent                                        AUDIO_SESSION_OUTPUT_MIX,
4821717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent                                        effect->id());
4822717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent        }
4823e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        status = playbackThread->attachAuxEffect(this, EffectId);
482465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
482565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return status;
482665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
482765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
482865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::PlaybackThread::Track::setAuxBuffer(int EffectId, int32_t *buffer)
482965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
483065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mAuxEffectId = EffectId;
483165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mAuxBuffer = buffer;
483265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
483365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4834a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurentbool AudioFlinger::PlaybackThread::Track::presentationComplete(size_t framesWritten,
4835a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                                                         size_t audioHalFrames)
4836a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent{
4837a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    // a track is considered presented when the total number of frames written to audio HAL
4838a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    // corresponds to the number of frames written when presentationComplete() is called for the
4839a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    // first time (mPresentationCompleteFrames == 0) plus the buffer filling status at that time.
4840a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    if (mPresentationCompleteFrames == 0) {
4841a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        mPresentationCompleteFrames = framesWritten + audioHalFrames;
4842a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        ALOGV("presentationComplete() reset: mPresentationCompleteFrames %d audioHalFrames %d",
4843a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                  mPresentationCompleteFrames, audioHalFrames);
4844a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    }
4845a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    if (framesWritten >= mPresentationCompleteFrames) {
4846a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        ALOGV("presentationComplete() session %d complete: framesWritten %d",
4847a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                  mSessionId, framesWritten);
4848a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE);
4849a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        return true;
4850a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    }
4851a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    return false;
4852a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent}
4853a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
4854a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurentvoid AudioFlinger::PlaybackThread::Track::triggerEvents(AudioSystem::sync_event_t type)
4855a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent{
4856a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    for (int i = 0; i < (int)mSyncEvents.size(); i++) {
4857a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        if (mSyncEvents[i]->type() == type) {
4858a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent            mSyncEvents[i]->trigger();
4859a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent            mSyncEvents.removeAt(i);
4860a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent            i--;
4861a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        }
4862a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    }
4863a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent}
4864a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
486558912562617941964939a4182cda71eaeb153d4bGlenn Kasten// implement VolumeBufferProvider interface
486658912562617941964939a4182cda71eaeb153d4bGlenn Kasten
486758912562617941964939a4182cda71eaeb153d4bGlenn Kastenuint32_t AudioFlinger::PlaybackThread::Track::getVolumeLR()
486858912562617941964939a4182cda71eaeb153d4bGlenn Kasten{
486958912562617941964939a4182cda71eaeb153d4bGlenn Kasten    // called by FastMixer, so not allowed to take any locks, block, or do I/O including logs
487058912562617941964939a4182cda71eaeb153d4bGlenn Kasten    ALOG_ASSERT(isFastTrack() && (mCblk != NULL));
487158912562617941964939a4182cda71eaeb153d4bGlenn Kasten    uint32_t vlr = mCblk->getVolumeLR();
487258912562617941964939a4182cda71eaeb153d4bGlenn Kasten    uint32_t vl = vlr & 0xFFFF;
487358912562617941964939a4182cda71eaeb153d4bGlenn Kasten    uint32_t vr = vlr >> 16;
487458912562617941964939a4182cda71eaeb153d4bGlenn Kasten    // track volumes come from shared memory, so can't be trusted and must be clamped
487558912562617941964939a4182cda71eaeb153d4bGlenn Kasten    if (vl > MAX_GAIN_INT) {
487658912562617941964939a4182cda71eaeb153d4bGlenn Kasten        vl = MAX_GAIN_INT;
487758912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
487858912562617941964939a4182cda71eaeb153d4bGlenn Kasten    if (vr > MAX_GAIN_INT) {
487958912562617941964939a4182cda71eaeb153d4bGlenn Kasten        vr = MAX_GAIN_INT;
488058912562617941964939a4182cda71eaeb153d4bGlenn Kasten    }
488158912562617941964939a4182cda71eaeb153d4bGlenn Kasten    // now apply the cached master volume and stream type volume;
488258912562617941964939a4182cda71eaeb153d4bGlenn Kasten    // this is trusted but lacks any synchronization or barrier so may be stale
488358912562617941964939a4182cda71eaeb153d4bGlenn Kasten    float v = mCachedVolume;
488458912562617941964939a4182cda71eaeb153d4bGlenn Kasten    vl *= v;
488558912562617941964939a4182cda71eaeb153d4bGlenn Kasten    vr *= v;
488658912562617941964939a4182cda71eaeb153d4bGlenn Kasten    // re-combine into U4.16
488758912562617941964939a4182cda71eaeb153d4bGlenn Kasten    vlr = (vr << 16) | (vl & 0xFFFF);
488858912562617941964939a4182cda71eaeb153d4bGlenn Kasten    // FIXME look at mute, pause, and stop flags
488958912562617941964939a4182cda71eaeb153d4bGlenn Kasten    return vlr;
489058912562617941964939a4182cda71eaeb153d4bGlenn Kasten}
4891a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
48922986460984580833161bdaabc7f17da1005a8961Eric Laurentstatus_t AudioFlinger::PlaybackThread::Track::setSyncEvent(const sp<SyncEvent>& event)
48932986460984580833161bdaabc7f17da1005a8961Eric Laurent{
48942986460984580833161bdaabc7f17da1005a8961Eric Laurent    if (mState == TERMINATED || mState == PAUSED ||
48952986460984580833161bdaabc7f17da1005a8961Eric Laurent            ((framesReady() == 0) && ((mSharedBuffer != 0) ||
48962986460984580833161bdaabc7f17da1005a8961Eric Laurent                                      (mState == STOPPED)))) {
48972986460984580833161bdaabc7f17da1005a8961Eric Laurent        ALOGW("Track::setSyncEvent() in invalid state %d on session %d %s mode, framesReady %d ",
48982986460984580833161bdaabc7f17da1005a8961Eric Laurent              mState, mSessionId, (mSharedBuffer != 0) ? "static" : "stream", framesReady());
48992986460984580833161bdaabc7f17da1005a8961Eric Laurent        event->cancel();
49002986460984580833161bdaabc7f17da1005a8961Eric Laurent        return INVALID_OPERATION;
49012986460984580833161bdaabc7f17da1005a8961Eric Laurent    }
4902d23eedca9b5a1812891c05d89850ab7ee707040dGlenn Kasten    (void) TrackBase::setSyncEvent(event);
49032986460984580833161bdaabc7f17da1005a8961Eric Laurent    return NO_ERROR;
49042986460984580833161bdaabc7f17da1005a8961Eric Laurent}
49052986460984580833161bdaabc7f17da1005a8961Eric Laurent
4906864585df53eb97c31e77b3ad7c0d89e4f9b42588Glenn Kastenbool AudioFlinger::PlaybackThread::Track::isOut() const
4907864585df53eb97c31e77b3ad7c0d89e4f9b42588Glenn Kasten{
4908864585df53eb97c31e77b3ad7c0d89e4f9b42588Glenn Kasten    return true;
4909864585df53eb97c31e77b3ad7c0d89e4f9b42588Glenn Kasten}
4910864585df53eb97c31e77b3ad7c0d89e4f9b42588Glenn Kasten
49114ff14bae91075eb274eb1c2975982358946e7e63John Grossman// timed audio tracks
49124ff14bae91075eb274eb1c2975982358946e7e63John Grossman
49134ff14bae91075eb274eb1c2975982358946e7e63John Grossmansp<AudioFlinger::PlaybackThread::TimedTrack>
49144ff14bae91075eb274eb1c2975982358946e7e63John GrossmanAudioFlinger::PlaybackThread::TimedTrack::create(
49159eaa55756c5b245970447019250ce852f5189525Glenn Kasten            PlaybackThread *thread,
49164ff14bae91075eb274eb1c2975982358946e7e63John Grossman            const sp<Client>& client,
49174ff14bae91075eb274eb1c2975982358946e7e63John Grossman            audio_stream_type_t streamType,
49184ff14bae91075eb274eb1c2975982358946e7e63John Grossman            uint32_t sampleRate,
49194ff14bae91075eb274eb1c2975982358946e7e63John Grossman            audio_format_t format,
4920254af180475346b6186b49c297f340c9c4817511Glenn Kasten            audio_channel_mask_t channelMask,
4921e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten            size_t frameCount,
49224ff14bae91075eb274eb1c2975982358946e7e63John Grossman            const sp<IMemory>& sharedBuffer,
49234ff14bae91075eb274eb1c2975982358946e7e63John Grossman            int sessionId) {
49244ff14bae91075eb274eb1c2975982358946e7e63John Grossman    if (!client->reserveTimedTrack())
4925d5903ec1332630f2992a6f0d5ca69d13a185c665Glenn Kasten        return 0;
49264ff14bae91075eb274eb1c2975982358946e7e63John Grossman
4927a03567676e8766828ff970b87e13bc4c97b23473Glenn Kasten    return new TimedTrack(
49284ff14bae91075eb274eb1c2975982358946e7e63John Grossman        thread, client, streamType, sampleRate, format, channelMask, frameCount,
49294ff14bae91075eb274eb1c2975982358946e7e63John Grossman        sharedBuffer, sessionId);
49304ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
49314ff14bae91075eb274eb1c2975982358946e7e63John Grossman
49324ff14bae91075eb274eb1c2975982358946e7e63John GrossmanAudioFlinger::PlaybackThread::TimedTrack::TimedTrack(
49339eaa55756c5b245970447019250ce852f5189525Glenn Kasten            PlaybackThread *thread,
49344ff14bae91075eb274eb1c2975982358946e7e63John Grossman            const sp<Client>& client,
49354ff14bae91075eb274eb1c2975982358946e7e63John Grossman            audio_stream_type_t streamType,
49364ff14bae91075eb274eb1c2975982358946e7e63John Grossman            uint32_t sampleRate,
49374ff14bae91075eb274eb1c2975982358946e7e63John Grossman            audio_format_t format,
4938254af180475346b6186b49c297f340c9c4817511Glenn Kasten            audio_channel_mask_t channelMask,
4939e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten            size_t frameCount,
49404ff14bae91075eb274eb1c2975982358946e7e63John Grossman            const sp<IMemory>& sharedBuffer,
49414ff14bae91075eb274eb1c2975982358946e7e63John Grossman            int sessionId)
49424ff14bae91075eb274eb1c2975982358946e7e63John Grossman    : Track(thread, client, streamType, sampleRate, format, channelMask,
494373d227557ba5192735356bacab9f77b44980793bGlenn Kasten            frameCount, sharedBuffer, sessionId, IAudioFlinger::TRACK_TIMED),
49449fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman      mQueueHeadInFlight(false),
49459fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman      mTrimQueueHeadOnRelease(false),
49461c345196edc61694f29307a1826a64a0d26028dcJohn Grossman      mFramesPendingInQueue(0),
49474ff14bae91075eb274eb1c2975982358946e7e63John Grossman      mTimedSilenceBuffer(NULL),
49484ff14bae91075eb274eb1c2975982358946e7e63John Grossman      mTimedSilenceBufferSize(0),
49494ff14bae91075eb274eb1c2975982358946e7e63John Grossman      mTimedAudioOutputOnTime(false),
49504ff14bae91075eb274eb1c2975982358946e7e63John Grossman      mMediaTimeTransformValid(false)
49514ff14bae91075eb274eb1c2975982358946e7e63John Grossman{
49524ff14bae91075eb274eb1c2975982358946e7e63John Grossman    LocalClock lc;
49534ff14bae91075eb274eb1c2975982358946e7e63John Grossman    mLocalTimeFreq = lc.getLocalFreq();
49544ff14bae91075eb274eb1c2975982358946e7e63John Grossman
49554ff14bae91075eb274eb1c2975982358946e7e63John Grossman    mLocalTimeToSampleTransform.a_zero = 0;
49564ff14bae91075eb274eb1c2975982358946e7e63John Grossman    mLocalTimeToSampleTransform.b_zero = 0;
49574ff14bae91075eb274eb1c2975982358946e7e63John Grossman    mLocalTimeToSampleTransform.a_to_b_numer = sampleRate;
49584ff14bae91075eb274eb1c2975982358946e7e63John Grossman    mLocalTimeToSampleTransform.a_to_b_denom = mLocalTimeFreq;
49594ff14bae91075eb274eb1c2975982358946e7e63John Grossman    LinearTransform::reduce(&mLocalTimeToSampleTransform.a_to_b_numer,
49604ff14bae91075eb274eb1c2975982358946e7e63John Grossman                            &mLocalTimeToSampleTransform.a_to_b_denom);
49619fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman
49629fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman    mMediaTimeToSampleTransform.a_zero = 0;
49639fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman    mMediaTimeToSampleTransform.b_zero = 0;
49649fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman    mMediaTimeToSampleTransform.a_to_b_numer = sampleRate;
49659fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman    mMediaTimeToSampleTransform.a_to_b_denom = 1000000;
49669fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman    LinearTransform::reduce(&mMediaTimeToSampleTransform.a_to_b_numer,
49679fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman                            &mMediaTimeToSampleTransform.a_to_b_denom);
49684ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
49694ff14bae91075eb274eb1c2975982358946e7e63John Grossman
49704ff14bae91075eb274eb1c2975982358946e7e63John GrossmanAudioFlinger::PlaybackThread::TimedTrack::~TimedTrack() {
49714ff14bae91075eb274eb1c2975982358946e7e63John Grossman    mClient->releaseTimedTrack();
49724ff14bae91075eb274eb1c2975982358946e7e63John Grossman    delete [] mTimedSilenceBuffer;
49734ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
49744ff14bae91075eb274eb1c2975982358946e7e63John Grossman
49754ff14bae91075eb274eb1c2975982358946e7e63John Grossmanstatus_t AudioFlinger::PlaybackThread::TimedTrack::allocateTimedBuffer(
49764ff14bae91075eb274eb1c2975982358946e7e63John Grossman    size_t size, sp<IMemory>* buffer) {
49774ff14bae91075eb274eb1c2975982358946e7e63John Grossman
49784ff14bae91075eb274eb1c2975982358946e7e63John Grossman    Mutex::Autolock _l(mTimedBufferQueueLock);
49794ff14bae91075eb274eb1c2975982358946e7e63John Grossman
49804ff14bae91075eb274eb1c2975982358946e7e63John Grossman    trimTimedBufferQueue_l();
49814ff14bae91075eb274eb1c2975982358946e7e63John Grossman
49824ff14bae91075eb274eb1c2975982358946e7e63John Grossman    // lazily initialize the shared memory heap for timed buffers
49834ff14bae91075eb274eb1c2975982358946e7e63John Grossman    if (mTimedMemoryDealer == NULL) {
49844ff14bae91075eb274eb1c2975982358946e7e63John Grossman        const int kTimedBufferHeapSize = 512 << 10;
49854ff14bae91075eb274eb1c2975982358946e7e63John Grossman
49864ff14bae91075eb274eb1c2975982358946e7e63John Grossman        mTimedMemoryDealer = new MemoryDealer(kTimedBufferHeapSize,
49874ff14bae91075eb274eb1c2975982358946e7e63John Grossman                                              "AudioFlingerTimed");
49884ff14bae91075eb274eb1c2975982358946e7e63John Grossman        if (mTimedMemoryDealer == NULL)
49894ff14bae91075eb274eb1c2975982358946e7e63John Grossman            return NO_MEMORY;
49904ff14bae91075eb274eb1c2975982358946e7e63John Grossman    }
49914ff14bae91075eb274eb1c2975982358946e7e63John Grossman
49924ff14bae91075eb274eb1c2975982358946e7e63John Grossman    sp<IMemory> newBuffer = mTimedMemoryDealer->allocate(size);
49934ff14bae91075eb274eb1c2975982358946e7e63John Grossman    if (newBuffer == NULL) {
49944ff14bae91075eb274eb1c2975982358946e7e63John Grossman        newBuffer = mTimedMemoryDealer->allocate(size);
49954ff14bae91075eb274eb1c2975982358946e7e63John Grossman        if (newBuffer == NULL)
49964ff14bae91075eb274eb1c2975982358946e7e63John Grossman            return NO_MEMORY;
49974ff14bae91075eb274eb1c2975982358946e7e63John Grossman    }
49984ff14bae91075eb274eb1c2975982358946e7e63John Grossman
49994ff14bae91075eb274eb1c2975982358946e7e63John Grossman    *buffer = newBuffer;
50004ff14bae91075eb274eb1c2975982358946e7e63John Grossman    return NO_ERROR;
50014ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
50024ff14bae91075eb274eb1c2975982358946e7e63John Grossman
50034ff14bae91075eb274eb1c2975982358946e7e63John Grossman// caller must hold mTimedBufferQueueLock
50044ff14bae91075eb274eb1c2975982358946e7e63John Grossmanvoid AudioFlinger::PlaybackThread::TimedTrack::trimTimedBufferQueue_l() {
50054ff14bae91075eb274eb1c2975982358946e7e63John Grossman    int64_t mediaTimeNow;
50064ff14bae91075eb274eb1c2975982358946e7e63John Grossman    {
50074ff14bae91075eb274eb1c2975982358946e7e63John Grossman        Mutex::Autolock mttLock(mMediaTimeTransformLock);
50084ff14bae91075eb274eb1c2975982358946e7e63John Grossman        if (!mMediaTimeTransformValid)
50094ff14bae91075eb274eb1c2975982358946e7e63John Grossman            return;
50104ff14bae91075eb274eb1c2975982358946e7e63John Grossman
50114ff14bae91075eb274eb1c2975982358946e7e63John Grossman        int64_t targetTimeNow;
50124ff14bae91075eb274eb1c2975982358946e7e63John Grossman        status_t res = (mMediaTimeTransformTarget == TimedAudioTrack::COMMON_TIME)
50134ff14bae91075eb274eb1c2975982358946e7e63John Grossman            ? mCCHelper.getCommonTime(&targetTimeNow)
50144ff14bae91075eb274eb1c2975982358946e7e63John Grossman            : mCCHelper.getLocalTime(&targetTimeNow);
50154ff14bae91075eb274eb1c2975982358946e7e63John Grossman
50164ff14bae91075eb274eb1c2975982358946e7e63John Grossman        if (OK != res)
50174ff14bae91075eb274eb1c2975982358946e7e63John Grossman            return;
50184ff14bae91075eb274eb1c2975982358946e7e63John Grossman
50194ff14bae91075eb274eb1c2975982358946e7e63John Grossman        if (!mMediaTimeTransform.doReverseTransform(targetTimeNow,
50204ff14bae91075eb274eb1c2975982358946e7e63John Grossman                                                    &mediaTimeNow)) {
50214ff14bae91075eb274eb1c2975982358946e7e63John Grossman            return;
50224ff14bae91075eb274eb1c2975982358946e7e63John Grossman        }
50234ff14bae91075eb274eb1c2975982358946e7e63John Grossman    }
50244ff14bae91075eb274eb1c2975982358946e7e63John Grossman
50251c345196edc61694f29307a1826a64a0d26028dcJohn Grossman    size_t trimEnd;
50261c345196edc61694f29307a1826a64a0d26028dcJohn Grossman    for (trimEnd = 0; trimEnd < mTimedBufferQueue.size(); trimEnd++) {
50279fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman        int64_t bufEnd;
50289fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman
5029c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman        if ((trimEnd + 1) < mTimedBufferQueue.size()) {
5030c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman            // We have a next buffer.  Just use its PTS as the PTS of the frame
5031c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman            // following the last frame in this buffer.  If the stream is sparse
5032c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman            // (ie, there are deliberate gaps left in the stream which should be
5033c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman            // filled with silence by the TimedAudioTrack), then this can result
5034c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman            // in one extra buffer being left un-trimmed when it could have
5035c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman            // been.  In general, this is not typical, and we would rather
5036c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman            // optimized away the TS calculation below for the more common case
5037c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman            // where PTSes are contiguous.
5038c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman            bufEnd = mTimedBufferQueue[trimEnd + 1].pts();
5039c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman        } else {
5040c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman            // We have no next buffer.  Compute the PTS of the frame following
5041c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman            // the last frame in this buffer by computing the duration of of
5042c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman            // this frame in media time units and adding it to the PTS of the
5043c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman            // buffer.
5044c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman            int64_t frameCount = mTimedBufferQueue[trimEnd].buffer()->size()
504583a0382dc17364567667a4e6135db43f5bd92efcGlenn Kasten                               / mFrameSize;
5046c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman
5047c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman            if (!mMediaTimeToSampleTransform.doReverseTransform(frameCount,
5048c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman                                                                &bufEnd)) {
5049c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman                ALOGE("Failed to convert frame count of %lld to media time"
5050c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman                      " duration" " (scale factor %d/%u) in %s",
5051c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman                      frameCount,
5052c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman                      mMediaTimeToSampleTransform.a_to_b_numer,
5053c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman                      mMediaTimeToSampleTransform.a_to_b_denom,
5054c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman                      __PRETTY_FUNCTION__);
5055c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman                break;
5056c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman            }
5057c95cfbb87d0ac5e773037019a96bfc29972d4b4eJohn Grossman            bufEnd += mTimedBufferQueue[trimEnd].pts();
50589fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman        }
50599fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman
50609fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman        if (bufEnd > mediaTimeNow)
50614ff14bae91075eb274eb1c2975982358946e7e63John Grossman            break;
50629fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman
50639fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman        // Is the buffer we want to use in the middle of a mix operation right
50649fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman        // now?  If so, don't actually trim it.  Just wait for the releaseBuffer
50659fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman        // from the mixer which should be coming back shortly.
50661c345196edc61694f29307a1826a64a0d26028dcJohn Grossman        if (!trimEnd && mQueueHeadInFlight) {
50679fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman            mTrimQueueHeadOnRelease = true;
50689fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman        }
50694ff14bae91075eb274eb1c2975982358946e7e63John Grossman    }
50704ff14bae91075eb274eb1c2975982358946e7e63John Grossman
50719fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman    size_t trimStart = mTrimQueueHeadOnRelease ? 1 : 0;
50721c345196edc61694f29307a1826a64a0d26028dcJohn Grossman    if (trimStart < trimEnd) {
50731c345196edc61694f29307a1826a64a0d26028dcJohn Grossman        // Update the bookkeeping for framesReady()
50741c345196edc61694f29307a1826a64a0d26028dcJohn Grossman        for (size_t i = trimStart; i < trimEnd; ++i) {
50751c345196edc61694f29307a1826a64a0d26028dcJohn Grossman            updateFramesPendingAfterTrim_l(mTimedBufferQueue[i], "trim");
50761c345196edc61694f29307a1826a64a0d26028dcJohn Grossman        }
50771c345196edc61694f29307a1826a64a0d26028dcJohn Grossman
50781c345196edc61694f29307a1826a64a0d26028dcJohn Grossman        // Now actually remove the buffers from the queue.
50791c345196edc61694f29307a1826a64a0d26028dcJohn Grossman        mTimedBufferQueue.removeItemsAt(trimStart, trimEnd);
50804ff14bae91075eb274eb1c2975982358946e7e63John Grossman    }
50814ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
50824ff14bae91075eb274eb1c2975982358946e7e63John Grossman
50831c345196edc61694f29307a1826a64a0d26028dcJohn Grossmanvoid AudioFlinger::PlaybackThread::TimedTrack::trimTimedBufferQueueHead_l(
50841c345196edc61694f29307a1826a64a0d26028dcJohn Grossman        const char* logTag) {
5085d3030da2ac3c0ebb8b7bdf38418263caf405b863John Grossman    ALOG_ASSERT(mTimedBufferQueue.size() > 0,
5086d3030da2ac3c0ebb8b7bdf38418263caf405b863John Grossman                "%s called (reason \"%s\"), but timed buffer queue has no"
5087d3030da2ac3c0ebb8b7bdf38418263caf405b863John Grossman                " elements to trim.", __FUNCTION__, logTag);
50881c345196edc61694f29307a1826a64a0d26028dcJohn Grossman
50891c345196edc61694f29307a1826a64a0d26028dcJohn Grossman    updateFramesPendingAfterTrim_l(mTimedBufferQueue[0], logTag);
50901c345196edc61694f29307a1826a64a0d26028dcJohn Grossman    mTimedBufferQueue.removeAt(0);
50911c345196edc61694f29307a1826a64a0d26028dcJohn Grossman}
50921c345196edc61694f29307a1826a64a0d26028dcJohn Grossman
50931c345196edc61694f29307a1826a64a0d26028dcJohn Grossmanvoid AudioFlinger::PlaybackThread::TimedTrack::updateFramesPendingAfterTrim_l(
50941c345196edc61694f29307a1826a64a0d26028dcJohn Grossman        const TimedBuffer& buf,
50951c345196edc61694f29307a1826a64a0d26028dcJohn Grossman        const char* logTag) {
50961c345196edc61694f29307a1826a64a0d26028dcJohn Grossman    uint32_t bufBytes        = buf.buffer()->size();
50971c345196edc61694f29307a1826a64a0d26028dcJohn Grossman    uint32_t consumedAlready = buf.position();
50981c345196edc61694f29307a1826a64a0d26028dcJohn Grossman
5099b388e531613730572067e193b6b66afb5d042233Eric Laurent    ALOG_ASSERT(consumedAlready <= bufBytes,
5100d3030da2ac3c0ebb8b7bdf38418263caf405b863John Grossman                "Bad bookkeeping while updating frames pending.  Timed buffer is"
5101d3030da2ac3c0ebb8b7bdf38418263caf405b863John Grossman                " only %u bytes long, but claims to have consumed %u"
5102d3030da2ac3c0ebb8b7bdf38418263caf405b863John Grossman                " bytes.  (update reason: \"%s\")",
5103b388e531613730572067e193b6b66afb5d042233Eric Laurent                bufBytes, consumedAlready, logTag);
51041c345196edc61694f29307a1826a64a0d26028dcJohn Grossman
510583a0382dc17364567667a4e6135db43f5bd92efcGlenn Kasten    uint32_t bufFrames = (bufBytes - consumedAlready) / mFrameSize;
5106d3030da2ac3c0ebb8b7bdf38418263caf405b863John Grossman    ALOG_ASSERT(mFramesPendingInQueue >= bufFrames,
5107d3030da2ac3c0ebb8b7bdf38418263caf405b863John Grossman                "Bad bookkeeping while updating frames pending.  Should have at"
5108d3030da2ac3c0ebb8b7bdf38418263caf405b863John Grossman                " least %u queued frames, but we think we have only %u.  (update"
5109d3030da2ac3c0ebb8b7bdf38418263caf405b863John Grossman                " reason: \"%s\")",
5110d3030da2ac3c0ebb8b7bdf38418263caf405b863John Grossman                bufFrames, mFramesPendingInQueue, logTag);
51111c345196edc61694f29307a1826a64a0d26028dcJohn Grossman
51121c345196edc61694f29307a1826a64a0d26028dcJohn Grossman    mFramesPendingInQueue -= bufFrames;
51131c345196edc61694f29307a1826a64a0d26028dcJohn Grossman}
51141c345196edc61694f29307a1826a64a0d26028dcJohn Grossman
51154ff14bae91075eb274eb1c2975982358946e7e63John Grossmanstatus_t AudioFlinger::PlaybackThread::TimedTrack::queueTimedBuffer(
51164ff14bae91075eb274eb1c2975982358946e7e63John Grossman    const sp<IMemory>& buffer, int64_t pts) {
51174ff14bae91075eb274eb1c2975982358946e7e63John Grossman
51184ff14bae91075eb274eb1c2975982358946e7e63John Grossman    {
51194ff14bae91075eb274eb1c2975982358946e7e63John Grossman        Mutex::Autolock mttLock(mMediaTimeTransformLock);
51204ff14bae91075eb274eb1c2975982358946e7e63John Grossman        if (!mMediaTimeTransformValid)
51214ff14bae91075eb274eb1c2975982358946e7e63John Grossman            return INVALID_OPERATION;
51224ff14bae91075eb274eb1c2975982358946e7e63John Grossman    }
51234ff14bae91075eb274eb1c2975982358946e7e63John Grossman
51244ff14bae91075eb274eb1c2975982358946e7e63John Grossman    Mutex::Autolock _l(mTimedBufferQueueLock);
51254ff14bae91075eb274eb1c2975982358946e7e63John Grossman
512683a0382dc17364567667a4e6135db43f5bd92efcGlenn Kasten    uint32_t bufFrames = buffer->size() / mFrameSize;
51271c345196edc61694f29307a1826a64a0d26028dcJohn Grossman    mFramesPendingInQueue += bufFrames;
51284ff14bae91075eb274eb1c2975982358946e7e63John Grossman    mTimedBufferQueue.add(TimedBuffer(buffer, pts));
51294ff14bae91075eb274eb1c2975982358946e7e63John Grossman
51304ff14bae91075eb274eb1c2975982358946e7e63John Grossman    return NO_ERROR;
51314ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
51324ff14bae91075eb274eb1c2975982358946e7e63John Grossman
51334ff14bae91075eb274eb1c2975982358946e7e63John Grossmanstatus_t AudioFlinger::PlaybackThread::TimedTrack::setMediaTimeTransform(
51344ff14bae91075eb274eb1c2975982358946e7e63John Grossman    const LinearTransform& xform, TimedAudioTrack::TargetTimeline target) {
51354ff14bae91075eb274eb1c2975982358946e7e63John Grossman
51361c345196edc61694f29307a1826a64a0d26028dcJohn Grossman    ALOGVV("setMediaTimeTransform az=%lld bz=%lld n=%d d=%u tgt=%d",
51371c345196edc61694f29307a1826a64a0d26028dcJohn Grossman           xform.a_zero, xform.b_zero, xform.a_to_b_numer, xform.a_to_b_denom,
51381c345196edc61694f29307a1826a64a0d26028dcJohn Grossman           target);
51394ff14bae91075eb274eb1c2975982358946e7e63John Grossman
51404ff14bae91075eb274eb1c2975982358946e7e63John Grossman    if (!(target == TimedAudioTrack::LOCAL_TIME ||
51414ff14bae91075eb274eb1c2975982358946e7e63John Grossman          target == TimedAudioTrack::COMMON_TIME)) {
51424ff14bae91075eb274eb1c2975982358946e7e63John Grossman        return BAD_VALUE;
51434ff14bae91075eb274eb1c2975982358946e7e63John Grossman    }
51444ff14bae91075eb274eb1c2975982358946e7e63John Grossman
51454ff14bae91075eb274eb1c2975982358946e7e63John Grossman    Mutex::Autolock lock(mMediaTimeTransformLock);
51464ff14bae91075eb274eb1c2975982358946e7e63John Grossman    mMediaTimeTransform = xform;
51474ff14bae91075eb274eb1c2975982358946e7e63John Grossman    mMediaTimeTransformTarget = target;
51484ff14bae91075eb274eb1c2975982358946e7e63John Grossman    mMediaTimeTransformValid = true;
51494ff14bae91075eb274eb1c2975982358946e7e63John Grossman
51504ff14bae91075eb274eb1c2975982358946e7e63John Grossman    return NO_ERROR;
51514ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
51524ff14bae91075eb274eb1c2975982358946e7e63John Grossman
51534ff14bae91075eb274eb1c2975982358946e7e63John Grossman#define min(a, b) ((a) < (b) ? (a) : (b))
51544ff14bae91075eb274eb1c2975982358946e7e63John Grossman
51554ff14bae91075eb274eb1c2975982358946e7e63John Grossman// implementation of getNextBuffer for tracks whose buffers have timestamps
51564ff14bae91075eb274eb1c2975982358946e7e63John Grossmanstatus_t AudioFlinger::PlaybackThread::TimedTrack::getNextBuffer(
51574ff14bae91075eb274eb1c2975982358946e7e63John Grossman    AudioBufferProvider::Buffer* buffer, int64_t pts)
51584ff14bae91075eb274eb1c2975982358946e7e63John Grossman{
51594ff14bae91075eb274eb1c2975982358946e7e63John Grossman    if (pts == AudioBufferProvider::kInvalidPTS) {
5160d5903ec1332630f2992a6f0d5ca69d13a185c665Glenn Kasten        buffer->raw = NULL;
51614ff14bae91075eb274eb1c2975982358946e7e63John Grossman        buffer->frameCount = 0;
51628d314b709fdd81bb64bdaa8d72a0b19c355cefb9John Grossman        mTimedAudioOutputOnTime = false;
51634ff14bae91075eb274eb1c2975982358946e7e63John Grossman        return INVALID_OPERATION;
51644ff14bae91075eb274eb1c2975982358946e7e63John Grossman    }
51654ff14bae91075eb274eb1c2975982358946e7e63John Grossman
51664ff14bae91075eb274eb1c2975982358946e7e63John Grossman    Mutex::Autolock _l(mTimedBufferQueueLock);
51674ff14bae91075eb274eb1c2975982358946e7e63John Grossman
51689fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman    ALOG_ASSERT(!mQueueHeadInFlight,
51699fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman                "getNextBuffer called without releaseBuffer!");
51709fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman
51714ff14bae91075eb274eb1c2975982358946e7e63John Grossman    while (true) {
51724ff14bae91075eb274eb1c2975982358946e7e63John Grossman
51734ff14bae91075eb274eb1c2975982358946e7e63John Grossman        // if we have no timed buffers, then fail
51744ff14bae91075eb274eb1c2975982358946e7e63John Grossman        if (mTimedBufferQueue.isEmpty()) {
5175d5903ec1332630f2992a6f0d5ca69d13a185c665Glenn Kasten            buffer->raw = NULL;
51764ff14bae91075eb274eb1c2975982358946e7e63John Grossman            buffer->frameCount = 0;
51774ff14bae91075eb274eb1c2975982358946e7e63John Grossman            return NOT_ENOUGH_DATA;
51784ff14bae91075eb274eb1c2975982358946e7e63John Grossman        }
51794ff14bae91075eb274eb1c2975982358946e7e63John Grossman
51804ff14bae91075eb274eb1c2975982358946e7e63John Grossman        TimedBuffer& head = mTimedBufferQueue.editItemAt(0);
51814ff14bae91075eb274eb1c2975982358946e7e63John Grossman
51824ff14bae91075eb274eb1c2975982358946e7e63John Grossman        // calculate the PTS of the head of the timed buffer queue expressed in
51834ff14bae91075eb274eb1c2975982358946e7e63John Grossman        // local time
51844ff14bae91075eb274eb1c2975982358946e7e63John Grossman        int64_t headLocalPTS;
51854ff14bae91075eb274eb1c2975982358946e7e63John Grossman        {
51864ff14bae91075eb274eb1c2975982358946e7e63John Grossman            Mutex::Autolock mttLock(mMediaTimeTransformLock);
51874ff14bae91075eb274eb1c2975982358946e7e63John Grossman
51885798d4ebf236357a4b13246f40e52b90a34d09a4Glenn Kasten            ALOG_ASSERT(mMediaTimeTransformValid, "media time transform invalid");
51894ff14bae91075eb274eb1c2975982358946e7e63John Grossman
51904ff14bae91075eb274eb1c2975982358946e7e63John Grossman            if (mMediaTimeTransform.a_to_b_denom == 0) {
51914ff14bae91075eb274eb1c2975982358946e7e63John Grossman                // the transform represents a pause, so yield silence
51929fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman                timedYieldSilence_l(buffer->frameCount, buffer);
51934ff14bae91075eb274eb1c2975982358946e7e63John Grossman                return NO_ERROR;
51944ff14bae91075eb274eb1c2975982358946e7e63John Grossman            }
51954ff14bae91075eb274eb1c2975982358946e7e63John Grossman
51964ff14bae91075eb274eb1c2975982358946e7e63John Grossman            int64_t transformedPTS;
51974ff14bae91075eb274eb1c2975982358946e7e63John Grossman            if (!mMediaTimeTransform.doForwardTransform(head.pts(),
51984ff14bae91075eb274eb1c2975982358946e7e63John Grossman                                                        &transformedPTS)) {
51994ff14bae91075eb274eb1c2975982358946e7e63John Grossman                // the transform failed.  this shouldn't happen, but if it does
52004ff14bae91075eb274eb1c2975982358946e7e63John Grossman                // then just drop this buffer
52014ff14bae91075eb274eb1c2975982358946e7e63John Grossman                ALOGW("timedGetNextBuffer transform failed");
5202d5903ec1332630f2992a6f0d5ca69d13a185c665Glenn Kasten                buffer->raw = NULL;
52034ff14bae91075eb274eb1c2975982358946e7e63John Grossman                buffer->frameCount = 0;
52041c345196edc61694f29307a1826a64a0d26028dcJohn Grossman                trimTimedBufferQueueHead_l("getNextBuffer; no transform");
52054ff14bae91075eb274eb1c2975982358946e7e63John Grossman                return NO_ERROR;
52064ff14bae91075eb274eb1c2975982358946e7e63John Grossman            }
52074ff14bae91075eb274eb1c2975982358946e7e63John Grossman
52084ff14bae91075eb274eb1c2975982358946e7e63John Grossman            if (mMediaTimeTransformTarget == TimedAudioTrack::COMMON_TIME) {
52094ff14bae91075eb274eb1c2975982358946e7e63John Grossman                if (OK != mCCHelper.commonTimeToLocalTime(transformedPTS,
52104ff14bae91075eb274eb1c2975982358946e7e63John Grossman                                                          &headLocalPTS)) {
5211d5903ec1332630f2992a6f0d5ca69d13a185c665Glenn Kasten                    buffer->raw = NULL;
52124ff14bae91075eb274eb1c2975982358946e7e63John Grossman                    buffer->frameCount = 0;
52134ff14bae91075eb274eb1c2975982358946e7e63John Grossman                    return INVALID_OPERATION;
52144ff14bae91075eb274eb1c2975982358946e7e63John Grossman                }
52154ff14bae91075eb274eb1c2975982358946e7e63John Grossman            } else {
52164ff14bae91075eb274eb1c2975982358946e7e63John Grossman                headLocalPTS = transformedPTS;
52174ff14bae91075eb274eb1c2975982358946e7e63John Grossman            }
52184ff14bae91075eb274eb1c2975982358946e7e63John Grossman        }
52194ff14bae91075eb274eb1c2975982358946e7e63John Grossman
52204ff14bae91075eb274eb1c2975982358946e7e63John Grossman        // adjust the head buffer's PTS to reflect the portion of the head buffer
52214ff14bae91075eb274eb1c2975982358946e7e63John Grossman        // that has already been consumed
52224ff14bae91075eb274eb1c2975982358946e7e63John Grossman        int64_t effectivePTS = headLocalPTS +
522383a0382dc17364567667a4e6135db43f5bd92efcGlenn Kasten                ((head.position() / mFrameSize) * mLocalTimeFreq / sampleRate());
52244ff14bae91075eb274eb1c2975982358946e7e63John Grossman
52254ff14bae91075eb274eb1c2975982358946e7e63John Grossman        // Calculate the delta in samples between the head of the input buffer
52264ff14bae91075eb274eb1c2975982358946e7e63John Grossman        // queue and the start of the next output buffer that will be written.
52274ff14bae91075eb274eb1c2975982358946e7e63John Grossman        // If the transformation fails because of over or underflow, it means
52284ff14bae91075eb274eb1c2975982358946e7e63John Grossman        // that the sample's position in the output stream is so far out of
52294ff14bae91075eb274eb1c2975982358946e7e63John Grossman        // whack that it should just be dropped.
52304ff14bae91075eb274eb1c2975982358946e7e63John Grossman        int64_t sampleDelta;
52314ff14bae91075eb274eb1c2975982358946e7e63John Grossman        if (llabs(effectivePTS - pts) >= (static_cast<int64_t>(1) << 31)) {
52324ff14bae91075eb274eb1c2975982358946e7e63John Grossman            ALOGV("*** head buffer is too far from PTS: dropped buffer");
52331c345196edc61694f29307a1826a64a0d26028dcJohn Grossman            trimTimedBufferQueueHead_l("getNextBuffer, buf pts too far from"
52341c345196edc61694f29307a1826a64a0d26028dcJohn Grossman                                       " mix");
52354ff14bae91075eb274eb1c2975982358946e7e63John Grossman            continue;
52364ff14bae91075eb274eb1c2975982358946e7e63John Grossman        }
52374ff14bae91075eb274eb1c2975982358946e7e63John Grossman        if (!mLocalTimeToSampleTransform.doForwardTransform(
52384ff14bae91075eb274eb1c2975982358946e7e63John Grossman                (effectivePTS - pts) << 32, &sampleDelta)) {
5239d3030da2ac3c0ebb8b7bdf38418263caf405b863John Grossman            ALOGV("*** too late during sample rate transform: dropped buffer");
52401c345196edc61694f29307a1826a64a0d26028dcJohn Grossman            trimTimedBufferQueueHead_l("getNextBuffer, bad local to sample");
52414ff14bae91075eb274eb1c2975982358946e7e63John Grossman            continue;
52424ff14bae91075eb274eb1c2975982358946e7e63John Grossman        }
52434ff14bae91075eb274eb1c2975982358946e7e63John Grossman
52441c345196edc61694f29307a1826a64a0d26028dcJohn Grossman        ALOGVV("*** getNextBuffer head.pts=%lld head.pos=%d pts=%lld"
52451c345196edc61694f29307a1826a64a0d26028dcJohn Grossman               " sampleDelta=[%d.%08x]",
52461c345196edc61694f29307a1826a64a0d26028dcJohn Grossman               head.pts(), head.position(), pts,
52471c345196edc61694f29307a1826a64a0d26028dcJohn Grossman               static_cast<int32_t>((sampleDelta >= 0 ? 0 : 1)
52481c345196edc61694f29307a1826a64a0d26028dcJohn Grossman                   + (sampleDelta >> 32)),
52491c345196edc61694f29307a1826a64a0d26028dcJohn Grossman               static_cast<uint32_t>(sampleDelta & 0xFFFFFFFF));
52504ff14bae91075eb274eb1c2975982358946e7e63John Grossman
52514ff14bae91075eb274eb1c2975982358946e7e63John Grossman        // if the delta between the ideal placement for the next input sample and
52524ff14bae91075eb274eb1c2975982358946e7e63John Grossman        // the current output position is within this threshold, then we will
52534ff14bae91075eb274eb1c2975982358946e7e63John Grossman        // concatenate the next input samples to the previous output
52544ff14bae91075eb274eb1c2975982358946e7e63John Grossman        const int64_t kSampleContinuityThreshold =
52558d314b709fdd81bb64bdaa8d72a0b19c355cefb9John Grossman                (static_cast<int64_t>(sampleRate()) << 32) / 250;
52564ff14bae91075eb274eb1c2975982358946e7e63John Grossman
52574ff14bae91075eb274eb1c2975982358946e7e63John Grossman        // if this is the first buffer of audio that we're emitting from this track
52584ff14bae91075eb274eb1c2975982358946e7e63John Grossman        // then it should be almost exactly on time.
52594ff14bae91075eb274eb1c2975982358946e7e63John Grossman        const int64_t kSampleStartupThreshold = 1LL << 32;
52604ff14bae91075eb274eb1c2975982358946e7e63John Grossman
52614ff14bae91075eb274eb1c2975982358946e7e63John Grossman        if ((mTimedAudioOutputOnTime && llabs(sampleDelta) <= kSampleContinuityThreshold) ||
52628d314b709fdd81bb64bdaa8d72a0b19c355cefb9John Grossman           (!mTimedAudioOutputOnTime && llabs(sampleDelta) <= kSampleStartupThreshold)) {
52634ff14bae91075eb274eb1c2975982358946e7e63John Grossman            // the next input is close enough to being on time, so concatenate it
52644ff14bae91075eb274eb1c2975982358946e7e63John Grossman            // with the last output
52659fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman            timedYieldSamples_l(buffer);
52664ff14bae91075eb274eb1c2975982358946e7e63John Grossman
52671c345196edc61694f29307a1826a64a0d26028dcJohn Grossman            ALOGVV("*** on time: head.pos=%d frameCount=%u",
52681c345196edc61694f29307a1826a64a0d26028dcJohn Grossman                    head.position(), buffer->frameCount);
52694ff14bae91075eb274eb1c2975982358946e7e63John Grossman            return NO_ERROR;
52708d314b709fdd81bb64bdaa8d72a0b19c355cefb9John Grossman        }
52718d314b709fdd81bb64bdaa8d72a0b19c355cefb9John Grossman
52728d314b709fdd81bb64bdaa8d72a0b19c355cefb9John Grossman        // Looks like our output is not on time.  Reset our on timed status.
52738d314b709fdd81bb64bdaa8d72a0b19c355cefb9John Grossman        // Next time we mix samples from our input queue, then should be within
52748d314b709fdd81bb64bdaa8d72a0b19c355cefb9John Grossman        // the StartupThreshold.
52758d314b709fdd81bb64bdaa8d72a0b19c355cefb9John Grossman        mTimedAudioOutputOnTime = false;
52768d314b709fdd81bb64bdaa8d72a0b19c355cefb9John Grossman        if (sampleDelta > 0) {
52774ff14bae91075eb274eb1c2975982358946e7e63John Grossman            // the gap between the current output position and the proper start of
52784ff14bae91075eb274eb1c2975982358946e7e63John Grossman            // the next input sample is too big, so fill it with silence
52794ff14bae91075eb274eb1c2975982358946e7e63John Grossman            uint32_t framesUntilNextInput = (sampleDelta + 0x80000000) >> 32;
52804ff14bae91075eb274eb1c2975982358946e7e63John Grossman
52819fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman            timedYieldSilence_l(framesUntilNextInput, buffer);
52824ff14bae91075eb274eb1c2975982358946e7e63John Grossman            ALOGV("*** silence: frameCount=%u", buffer->frameCount);
52834ff14bae91075eb274eb1c2975982358946e7e63John Grossman            return NO_ERROR;
52844ff14bae91075eb274eb1c2975982358946e7e63John Grossman        } else {
52854ff14bae91075eb274eb1c2975982358946e7e63John Grossman            // the next input sample is late
52864ff14bae91075eb274eb1c2975982358946e7e63John Grossman            uint32_t lateFrames = static_cast<uint32_t>(-((sampleDelta + 0x80000000) >> 32));
52874ff14bae91075eb274eb1c2975982358946e7e63John Grossman            size_t onTimeSamplePosition =
528883a0382dc17364567667a4e6135db43f5bd92efcGlenn Kasten                    head.position() + lateFrames * mFrameSize;
52894ff14bae91075eb274eb1c2975982358946e7e63John Grossman
52904ff14bae91075eb274eb1c2975982358946e7e63John Grossman            if (onTimeSamplePosition > head.buffer()->size()) {
52914ff14bae91075eb274eb1c2975982358946e7e63John Grossman                // all the remaining samples in the head are too late, so
52924ff14bae91075eb274eb1c2975982358946e7e63John Grossman                // drop it and move on
52934ff14bae91075eb274eb1c2975982358946e7e63John Grossman                ALOGV("*** too late: dropped buffer");
52941c345196edc61694f29307a1826a64a0d26028dcJohn Grossman                trimTimedBufferQueueHead_l("getNextBuffer, dropped late buffer");
52954ff14bae91075eb274eb1c2975982358946e7e63John Grossman                continue;
52964ff14bae91075eb274eb1c2975982358946e7e63John Grossman            } else {
52974ff14bae91075eb274eb1c2975982358946e7e63John Grossman                // skip over the late samples
52984ff14bae91075eb274eb1c2975982358946e7e63John Grossman                head.setPosition(onTimeSamplePosition);
52994ff14bae91075eb274eb1c2975982358946e7e63John Grossman
53004ff14bae91075eb274eb1c2975982358946e7e63John Grossman                // yield the available samples
53019fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman                timedYieldSamples_l(buffer);
53024ff14bae91075eb274eb1c2975982358946e7e63John Grossman
53034ff14bae91075eb274eb1c2975982358946e7e63John Grossman                ALOGV("*** late: head.pos=%d frameCount=%u", head.position(), buffer->frameCount);
53044ff14bae91075eb274eb1c2975982358946e7e63John Grossman                return NO_ERROR;
53054ff14bae91075eb274eb1c2975982358946e7e63John Grossman            }
53064ff14bae91075eb274eb1c2975982358946e7e63John Grossman        }
53074ff14bae91075eb274eb1c2975982358946e7e63John Grossman    }
53084ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
53094ff14bae91075eb274eb1c2975982358946e7e63John Grossman
53104ff14bae91075eb274eb1c2975982358946e7e63John Grossman// Yield samples from the timed buffer queue head up to the given output
53114ff14bae91075eb274eb1c2975982358946e7e63John Grossman// buffer's capacity.
53124ff14bae91075eb274eb1c2975982358946e7e63John Grossman//
53134ff14bae91075eb274eb1c2975982358946e7e63John Grossman// Caller must hold mTimedBufferQueueLock
53149fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossmanvoid AudioFlinger::PlaybackThread::TimedTrack::timedYieldSamples_l(
53154ff14bae91075eb274eb1c2975982358946e7e63John Grossman    AudioBufferProvider::Buffer* buffer) {
53164ff14bae91075eb274eb1c2975982358946e7e63John Grossman
53174ff14bae91075eb274eb1c2975982358946e7e63John Grossman    const TimedBuffer& head = mTimedBufferQueue[0];
53184ff14bae91075eb274eb1c2975982358946e7e63John Grossman
53194ff14bae91075eb274eb1c2975982358946e7e63John Grossman    buffer->raw = (static_cast<uint8_t*>(head.buffer()->pointer()) +
53204ff14bae91075eb274eb1c2975982358946e7e63John Grossman                   head.position());
53214ff14bae91075eb274eb1c2975982358946e7e63John Grossman
53224ff14bae91075eb274eb1c2975982358946e7e63John Grossman    uint32_t framesLeftInHead = ((head.buffer()->size() - head.position()) /
532383a0382dc17364567667a4e6135db43f5bd92efcGlenn Kasten                                 mFrameSize);
53244ff14bae91075eb274eb1c2975982358946e7e63John Grossman    size_t framesRequested = buffer->frameCount;
53254ff14bae91075eb274eb1c2975982358946e7e63John Grossman    buffer->frameCount = min(framesLeftInHead, framesRequested);
53264ff14bae91075eb274eb1c2975982358946e7e63John Grossman
53279fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman    mQueueHeadInFlight = true;
53284ff14bae91075eb274eb1c2975982358946e7e63John Grossman    mTimedAudioOutputOnTime = true;
53294ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
53304ff14bae91075eb274eb1c2975982358946e7e63John Grossman
53314ff14bae91075eb274eb1c2975982358946e7e63John Grossman// Yield samples of silence up to the given output buffer's capacity
53324ff14bae91075eb274eb1c2975982358946e7e63John Grossman//
53334ff14bae91075eb274eb1c2975982358946e7e63John Grossman// Caller must hold mTimedBufferQueueLock
53349fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossmanvoid AudioFlinger::PlaybackThread::TimedTrack::timedYieldSilence_l(
53354ff14bae91075eb274eb1c2975982358946e7e63John Grossman    uint32_t numFrames, AudioBufferProvider::Buffer* buffer) {
53364ff14bae91075eb274eb1c2975982358946e7e63John Grossman
53374ff14bae91075eb274eb1c2975982358946e7e63John Grossman    // lazily allocate a buffer filled with silence
533883a0382dc17364567667a4e6135db43f5bd92efcGlenn Kasten    if (mTimedSilenceBufferSize < numFrames * mFrameSize) {
53394ff14bae91075eb274eb1c2975982358946e7e63John Grossman        delete [] mTimedSilenceBuffer;
534083a0382dc17364567667a4e6135db43f5bd92efcGlenn Kasten        mTimedSilenceBufferSize = numFrames * mFrameSize;
53414ff14bae91075eb274eb1c2975982358946e7e63John Grossman        mTimedSilenceBuffer = new uint8_t[mTimedSilenceBufferSize];
53424ff14bae91075eb274eb1c2975982358946e7e63John Grossman        memset(mTimedSilenceBuffer, 0, mTimedSilenceBufferSize);
53434ff14bae91075eb274eb1c2975982358946e7e63John Grossman    }
53444ff14bae91075eb274eb1c2975982358946e7e63John Grossman
53454ff14bae91075eb274eb1c2975982358946e7e63John Grossman    buffer->raw = mTimedSilenceBuffer;
53464ff14bae91075eb274eb1c2975982358946e7e63John Grossman    size_t framesRequested = buffer->frameCount;
53474ff14bae91075eb274eb1c2975982358946e7e63John Grossman    buffer->frameCount = min(numFrames, framesRequested);
53484ff14bae91075eb274eb1c2975982358946e7e63John Grossman
53494ff14bae91075eb274eb1c2975982358946e7e63John Grossman    mTimedAudioOutputOnTime = false;
53504ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
53514ff14bae91075eb274eb1c2975982358946e7e63John Grossman
535201c4ebf6b794493898114a502ed36de13137f7e5Glenn Kasten// AudioBufferProvider interface
53534ff14bae91075eb274eb1c2975982358946e7e63John Grossmanvoid AudioFlinger::PlaybackThread::TimedTrack::releaseBuffer(
53544ff14bae91075eb274eb1c2975982358946e7e63John Grossman    AudioBufferProvider::Buffer* buffer) {
53554ff14bae91075eb274eb1c2975982358946e7e63John Grossman
53564ff14bae91075eb274eb1c2975982358946e7e63John Grossman    Mutex::Autolock _l(mTimedBufferQueueLock);
53574ff14bae91075eb274eb1c2975982358946e7e63John Grossman
5358fe5b3ba4b332d5fc9aa4f453434329b9f38768c2John Grossman    // If the buffer which was just released is part of the buffer at the head
5359fe5b3ba4b332d5fc9aa4f453434329b9f38768c2John Grossman    // of the queue, be sure to update the amt of the buffer which has been
5360fe5b3ba4b332d5fc9aa4f453434329b9f38768c2John Grossman    // consumed.  If the buffer being returned is not part of the head of the
5361fe5b3ba4b332d5fc9aa4f453434329b9f38768c2John Grossman    // queue, its either because the buffer is part of the silence buffer, or
5362fe5b3ba4b332d5fc9aa4f453434329b9f38768c2John Grossman    // because the head of the timed queue was trimmed after the mixer called
5363fe5b3ba4b332d5fc9aa4f453434329b9f38768c2John Grossman    // getNextBuffer but before the mixer called releaseBuffer.
53649fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman    if (buffer->raw == mTimedSilenceBuffer) {
53659fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman        ALOG_ASSERT(!mQueueHeadInFlight,
53669fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman                    "Queue head in flight during release of silence buffer!");
53679fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman        goto done;
53689fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman    }
53699fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman
53709fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman    ALOG_ASSERT(mQueueHeadInFlight,
53719fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman                "TimedTrack::releaseBuffer of non-silence buffer, but no queue"
53729fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman                " head in flight.");
53739fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman
53749fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman    if (mTimedBufferQueue.size()) {
53754ff14bae91075eb274eb1c2975982358946e7e63John Grossman        TimedBuffer& head = mTimedBufferQueue.editItemAt(0);
5376fe5b3ba4b332d5fc9aa4f453434329b9f38768c2John Grossman
5377fe5b3ba4b332d5fc9aa4f453434329b9f38768c2John Grossman        void* start = head.buffer()->pointer();
53789fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman        void* end   = reinterpret_cast<void*>(
53799fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman                        reinterpret_cast<uint8_t*>(head.buffer()->pointer())
53809fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman                        + head.buffer()->size());
5381fe5b3ba4b332d5fc9aa4f453434329b9f38768c2John Grossman
53829fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman        ALOG_ASSERT((buffer->raw >= start) && (buffer->raw < end),
53839fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman                    "released buffer not within the head of the timed buffer"
53849fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman                    " queue; qHead = [%p, %p], released buffer = %p",
53859fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman                    start, end, buffer->raw);
53869fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman
53879fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman        head.setPosition(head.position() +
538883a0382dc17364567667a4e6135db43f5bd92efcGlenn Kasten                (buffer->frameCount * mFrameSize));
53899fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman        mQueueHeadInFlight = false;
53909fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman
53911c345196edc61694f29307a1826a64a0d26028dcJohn Grossman        ALOG_ASSERT(mFramesPendingInQueue >= buffer->frameCount,
53921c345196edc61694f29307a1826a64a0d26028dcJohn Grossman                    "Bad bookkeeping during releaseBuffer!  Should have at"
53931c345196edc61694f29307a1826a64a0d26028dcJohn Grossman                    " least %u queued frames, but we think we have only %u",
53941c345196edc61694f29307a1826a64a0d26028dcJohn Grossman                    buffer->frameCount, mFramesPendingInQueue);
53951c345196edc61694f29307a1826a64a0d26028dcJohn Grossman
53961c345196edc61694f29307a1826a64a0d26028dcJohn Grossman        mFramesPendingInQueue -= buffer->frameCount;
53971c345196edc61694f29307a1826a64a0d26028dcJohn Grossman
53989fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman        if ((static_cast<size_t>(head.position()) >= head.buffer()->size())
53999fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman            || mTrimQueueHeadOnRelease) {
54001c345196edc61694f29307a1826a64a0d26028dcJohn Grossman            trimTimedBufferQueueHead_l("releaseBuffer");
54019fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman            mTrimQueueHeadOnRelease = false;
54024ff14bae91075eb274eb1c2975982358946e7e63John Grossman        }
54039fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman    } else {
54049fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman        LOG_FATAL("TimedTrack::releaseBuffer of non-silence buffer with no"
54059fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossman                  " buffers in the timed buffer queue");
54064ff14bae91075eb274eb1c2975982358946e7e63John Grossman    }
54074ff14bae91075eb274eb1c2975982358946e7e63John Grossman
54089fbdee13d09447550dd22ae72c2dbabdce7f0a80John Grossmandone:
54094ff14bae91075eb274eb1c2975982358946e7e63John Grossman    buffer->raw = 0;
54104ff14bae91075eb274eb1c2975982358946e7e63John Grossman    buffer->frameCount = 0;
54114ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
54124ff14bae91075eb274eb1c2975982358946e7e63John Grossman
5413288ed2103d96f3aabd7e6bea3c080ab6db164049Glenn Kastensize_t AudioFlinger::PlaybackThread::TimedTrack::framesReady() const {
54144ff14bae91075eb274eb1c2975982358946e7e63John Grossman    Mutex::Autolock _l(mTimedBufferQueueLock);
54151c345196edc61694f29307a1826a64a0d26028dcJohn Grossman    return mFramesPendingInQueue;
54164ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
54174ff14bae91075eb274eb1c2975982358946e7e63John Grossman
54184ff14bae91075eb274eb1c2975982358946e7e63John GrossmanAudioFlinger::PlaybackThread::TimedTrack::TimedBuffer::TimedBuffer()
54194ff14bae91075eb274eb1c2975982358946e7e63John Grossman        : mPTS(0), mPosition(0) {}
54204ff14bae91075eb274eb1c2975982358946e7e63John Grossman
54214ff14bae91075eb274eb1c2975982358946e7e63John GrossmanAudioFlinger::PlaybackThread::TimedTrack::TimedBuffer::TimedBuffer(
54224ff14bae91075eb274eb1c2975982358946e7e63John Grossman    const sp<IMemory>& buffer, int64_t pts)
54234ff14bae91075eb274eb1c2975982358946e7e63John Grossman        : mBuffer(buffer), mPTS(pts), mPosition(0) {}
54244ff14bae91075eb274eb1c2975982358946e7e63John Grossman
542565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
542665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
542765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// RecordTrack constructor must be called with AudioFlinger::mLock held
542865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::RecordThread::RecordTrack::RecordTrack(
54299eaa55756c5b245970447019250ce852f5189525Glenn Kasten            RecordThread *thread,
543065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            const sp<Client>& client,
543165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            uint32_t sampleRate,
543258f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten            audio_format_t format,
5433254af180475346b6186b49c297f340c9c4817511Glenn Kasten            audio_channel_mask_t channelMask,
5434e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten            size_t frameCount,
543565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            int sessionId)
543665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    :   TrackBase(thread, client, sampleRate, format,
54375cf034d92d901169ca6e36c90475f40715827fcdGlenn Kasten                  channelMask, frameCount, 0 /*sharedBuffer*/, sessionId),
543865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mOverflow(false)
543965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
544083a0382dc17364567667a4e6135db43f5bd92efcGlenn Kasten    ALOGV("RecordTrack constructor, size %d", (int)mBufferEnd - (int)mBuffer);
544165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
544265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
544365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::RecordThread::RecordTrack::~RecordTrack()
544465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
5445510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    ALOGV("%s", __func__);
544665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
544765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
544801c4ebf6b794493898114a502ed36de13137f7e5Glenn Kasten// AudioBufferProvider interface
544985ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kastenstatus_t AudioFlinger::RecordThread::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer,
545085ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten        int64_t pts)
545165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
545265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    audio_track_cblk_t* cblk = this->cblk();
545365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    uint32_t framesAvail;
545465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    uint32_t framesReq = buffer->frameCount;
545565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5456e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    // Check if last stepServer failed, try to step now
54575cf034d92d901169ca6e36c90475f40715827fcdGlenn Kasten    if (mStepServerFailed) {
5458d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        if (!step()) {
5459d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten            goto getNextBuffer_exit;
5460d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        }
54613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("stepServer recovered");
54625cf034d92d901169ca6e36c90475f40715827fcdGlenn Kasten        mStepServerFailed = false;
546365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
546465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5465864585df53eb97c31e77b3ad7c0d89e4f9b42588Glenn Kasten    // FIXME lock is not actually held, so overrun is possible
5466864585df53eb97c31e77b3ad7c0d89e4f9b42588Glenn Kasten    framesAvail = cblk->framesAvailableIn_l();
546765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5468f6b1678f8f508b447155a81b44e214475ab634a8Glenn Kasten    if (CC_LIKELY(framesAvail)) {
546965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        uint32_t s = cblk->server;
547065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        uint32_t bufferEnd = cblk->serverBase + cblk->frameCount;
547165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
547265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (framesReq > framesAvail) {
547365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            framesReq = framesAvail;
547465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
5475a1472d9883e35edd280201c8be3191695007dfd4Marco Nelissen        if (framesReq > bufferEnd - s) {
547665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            framesReq = bufferEnd - s;
547765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
547865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
547965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        buffer->raw = getBuffer(s, framesReq);
548065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        buffer->frameCount = framesReq;
548165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NO_ERROR;
548265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
548365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
548465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopiangetNextBuffer_exit:
5485e0feee3da22beeffbd9357540e265f13b2119cbbGlenn Kasten    buffer->raw = NULL;
548665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    buffer->frameCount = 0;
548765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NOT_ENOUGH_DATA;
548865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
548965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
54903acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kastenstatus_t AudioFlinger::RecordThread::RecordTrack::start(AudioSystem::sync_event_t event,
5491a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                                                        int triggerSession)
549265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
549365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<ThreadBase> thread = mThread.promote();
549465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread != 0) {
549565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        RecordThread *recordThread = (RecordThread *)thread.get();
54963acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten        return recordThread->start(this, event, triggerSession);
549765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
549865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return BAD_VALUE;
549965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
550065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
550165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
550265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::RecordThread::RecordTrack::stop()
550365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
550465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<ThreadBase> thread = mThread.promote();
550565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread != 0) {
550665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        RecordThread *recordThread = (RecordThread *)thread.get();
55071d491ff06f4b9c90ff24fe953b90d0843eaf1c04Glenn Kasten        recordThread->mLock.lock();
55081d491ff06f4b9c90ff24fe953b90d0843eaf1c04Glenn Kasten        bool doStop = recordThread->stop_l(this);
55091d491ff06f4b9c90ff24fe953b90d0843eaf1c04Glenn Kasten        if (doStop) {
55101d491ff06f4b9c90ff24fe953b90d0843eaf1c04Glenn Kasten            TrackBase::reset();
55111d491ff06f4b9c90ff24fe953b90d0843eaf1c04Glenn Kasten            // Force overrun condition to avoid false overrun callback until first data is
55121d491ff06f4b9c90ff24fe953b90d0843eaf1c04Glenn Kasten            // read from buffer
55139c5fdd83f9b9f49be35107971feb33528d60b945Glenn Kasten            android_atomic_or(CBLK_UNDERRUN, &mCblk->flags);
55141d491ff06f4b9c90ff24fe953b90d0843eaf1c04Glenn Kasten        }
55151d491ff06f4b9c90ff24fe953b90d0843eaf1c04Glenn Kasten        recordThread->mLock.unlock();
55161d491ff06f4b9c90ff24fe953b90d0843eaf1c04Glenn Kasten        if (doStop) {
55171d491ff06f4b9c90ff24fe953b90d0843eaf1c04Glenn Kasten            AudioSystem::stopInput(recordThread->id());
55181d491ff06f4b9c90ff24fe953b90d0843eaf1c04Glenn Kasten        }
551965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
552065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
552165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5522510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten/*static*/ void AudioFlinger::RecordThread::RecordTrack::appendDumpHeader(String8& result)
5523510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten{
55249f2016d9adfb4f88fa0bbfcfa5954f79160db595Glenn Kasten    result.append("   Clien Fmt Chn mask   Session Step S SRate  Serv     User   FrameCount\n");
5525510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten}
5526510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten
552765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::RecordThread::RecordTrack::dump(char* buffer, size_t size)
552865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
552952762410dbc9189cd92a4094a1dbd4cfe8e71cb6Jean-Michel Trivi    snprintf(buffer, size, "   %05d %03u 0x%08x %05d   %04u %01d %05u  %08x %08x %05d\n",
553044deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten            (mClient == 0) ? getpid_cached : mClient->pid(),
553165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mFormat,
55320d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi            mChannelMask,
553365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mSessionId,
55349f2016d9adfb4f88fa0bbfcfa5954f79160db595Glenn Kasten            mStepCount,
553565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mState,
553665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mCblk->sampleRate,
553765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mCblk->server,
553852762410dbc9189cd92a4094a1dbd4cfe8e71cb6Jean-Michel Trivi            mCblk->user,
553952762410dbc9189cd92a4094a1dbd4cfe8e71cb6Jean-Michel Trivi            mCblk->frameCount);
554065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
554165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5542864585df53eb97c31e77b3ad7c0d89e4f9b42588Glenn Kastenbool AudioFlinger::RecordThread::RecordTrack::isOut() const
5543864585df53eb97c31e77b3ad7c0d89e4f9b42588Glenn Kasten{
5544864585df53eb97c31e77b3ad7c0d89e4f9b42588Glenn Kasten    return false;
5545864585df53eb97c31e77b3ad7c0d89e4f9b42588Glenn Kasten}
554665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
554765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
554865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
554965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::PlaybackThread::OutputTrack::OutputTrack(
55509eaa55756c5b245970447019250ce852f5189525Glenn Kasten            PlaybackThread *playbackThread,
555165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            DuplicatingThread *sourceThread,
555265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            uint32_t sampleRate,
555358f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten            audio_format_t format,
5554254af180475346b6186b49c297f340c9c4817511Glenn Kasten            audio_channel_mask_t channelMask,
5555e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten            size_t frameCount)
555673d227557ba5192735356bacab9f77b44980793bGlenn Kasten    :   Track(playbackThread, NULL, AUDIO_STREAM_CNT, sampleRate, format, channelMask, frameCount,
555773d227557ba5192735356bacab9f77b44980793bGlenn Kasten                NULL, 0, IAudioFlinger::TRACK_DEFAULT),
5558b929e417853694e37aba1ef4399f188987b709d9Glenn Kasten    mActive(false), mSourceThread(sourceThread), mBuffers(NULL)
555965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
556065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
556165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mCblk != NULL) {
5562b929e417853694e37aba1ef4399f188987b709d9Glenn Kasten        mBuffers = (char*)mCblk + sizeof(audio_track_cblk_t);
556365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mOutBuffer.frameCount = 0;
556465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        playbackThread->mTracks.add(this);
55653856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("OutputTrack constructor mCblk %p, mBuffer %p, mCblk->buffers %p, " \
55663b16c766d1ae2cfd8487e8ffb2b23936fc0a8e17Glenn Kasten                "mCblk->frameCount %d, mCblk->sampleRate %u, mChannelMask 0x%08x mBufferEnd %p",
55670d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi                mCblk, mBuffer, mCblk->buffers,
55680d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi                mCblk->frameCount, mCblk->sampleRate, mChannelMask, mBufferEnd);
556965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
55705ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Error creating output track on thread %p", playbackThread);
557165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
557265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
557365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
557465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::PlaybackThread::OutputTrack::~OutputTrack()
557565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
557665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    clearBufferQueue();
557765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
557865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
55793acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kastenstatus_t AudioFlinger::PlaybackThread::OutputTrack::start(AudioSystem::sync_event_t event,
5580a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                                                          int triggerSession)
558165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
55823acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten    status_t status = Track::start(event, triggerSession);
558365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (status != NO_ERROR) {
558465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return status;
558565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
558665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
558765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mActive = true;
558865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mRetryCount = 127;
558965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return status;
559065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
559165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
559265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::PlaybackThread::OutputTrack::stop()
559365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
559465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Track::stop();
559565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    clearBufferQueue();
559665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mOutBuffer.frameCount = 0;
559765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mActive = false;
559865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
559965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
560065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool AudioFlinger::PlaybackThread::OutputTrack::write(int16_t* data, uint32_t frames)
560165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
560265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Buffer *pInBuffer;
560365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Buffer inBuffer;
56040d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi    uint32_t channelCount = mChannelCount;
560565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool outputBufferFull = false;
560665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    inBuffer.frameCount = frames;
560765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    inBuffer.i16 = data;
560865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
560965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    uint32_t waitTimeLeftMs = mSourceThread->waitTimeMs();
561065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
561165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!mActive && frames != 0) {
56123acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten        start();
561365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<ThreadBase> thread = mThread.promote();
561465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (thread != 0) {
561565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            MixerThread *mixerThread = (MixerThread *)thread.get();
561665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (mCblk->frameCount > frames){
561765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (mBufferQueue.size() < kMaxOverFlowBuffers) {
561865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    uint32_t startFrames = (mCblk->frameCount - frames);
561965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    pInBuffer = new Buffer;
562065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    pInBuffer->mBuffer = new int16_t[startFrames * channelCount];
562165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    pInBuffer->frameCount = startFrames;
562265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    pInBuffer->i16 = pInBuffer->mBuffer;
562365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    memset(pInBuffer->raw, 0, startFrames * channelCount * sizeof(int16_t));
562465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mBufferQueue.add(pInBuffer);
562565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                } else {
56265ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block                    ALOGW ("OutputTrack::write() %p no more buffers in queue", this);
562765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
562865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
562965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
563065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
563165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
563265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    while (waitTimeLeftMs) {
563365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // First write pending buffers, then new data
563465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mBufferQueue.size()) {
563565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            pInBuffer = mBufferQueue.itemAt(0);
563665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
563765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            pInBuffer = &inBuffer;
563865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
563965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
564065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (pInBuffer->frameCount == 0) {
564165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
564265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
564365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
564465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mOutBuffer.frameCount == 0) {
564565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mOutBuffer.frameCount = pInBuffer->frameCount;
564665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            nsecs_t startTime = systemTime();
5647335787fe43596f38ea2fa50b24c54d0823a3fb1dGlenn Kasten            if (obtainBuffer(&mOutBuffer, waitTimeLeftMs) == (status_t)NO_MORE_BUFFERS) {
564885ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                ALOGV ("OutputTrack::write() %p thread %p no more output buffers", this,
564985ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                        mThread.unsafe_get());
565065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                outputBufferFull = true;
565165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                break;
565265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
565365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            uint32_t waitTimeMs = (uint32_t)ns2ms(systemTime() - startTime);
565465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (waitTimeLeftMs >= waitTimeMs) {
565565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                waitTimeLeftMs -= waitTimeMs;
565665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else {
565765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                waitTimeLeftMs = 0;
565865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
565965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
566065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
566185ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten        uint32_t outFrames = pInBuffer->frameCount > mOutBuffer.frameCount ? mOutBuffer.frameCount :
566285ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                pInBuffer->frameCount;
566365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        memcpy(mOutBuffer.raw, pInBuffer->raw, outFrames * channelCount * sizeof(int16_t));
5664864585df53eb97c31e77b3ad7c0d89e4f9b42588Glenn Kasten        mCblk->stepUserOut(outFrames);
566565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        pInBuffer->frameCount -= outFrames;
566665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        pInBuffer->i16 += outFrames * channelCount;
566765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mOutBuffer.frameCount -= outFrames;
566865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mOutBuffer.i16 += outFrames * channelCount;
566965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
567065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (pInBuffer->frameCount == 0) {
567165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (mBufferQueue.size()) {
567265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mBufferQueue.removeAt(0);
567365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                delete [] pInBuffer->mBuffer;
567465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                delete pInBuffer;
567585ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                ALOGV("OutputTrack::write() %p thread %p released overflow buffer %d", this,
567685ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                        mThread.unsafe_get(), mBufferQueue.size());
567765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else {
567865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                break;
567965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
568065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
568165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
568265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
568365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // If we could not write all frames, allocate a buffer and queue it for next time.
568465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (inBuffer.frameCount) {
568565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<ThreadBase> thread = mThread.promote();
568665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (thread != 0 && !thread->standby()) {
568765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (mBufferQueue.size() < kMaxOverFlowBuffers) {
568865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                pInBuffer = new Buffer;
568965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                pInBuffer->mBuffer = new int16_t[inBuffer.frameCount * channelCount];
569065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                pInBuffer->frameCount = inBuffer.frameCount;
569165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                pInBuffer->i16 = pInBuffer->mBuffer;
569285ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                memcpy(pInBuffer->raw, inBuffer.raw, inBuffer.frameCount * channelCount *
569385ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                        sizeof(int16_t));
569465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mBufferQueue.add(pInBuffer);
569585ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                ALOGV("OutputTrack::write() %p thread %p adding overflow buffer %d", this,
569685ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                        mThread.unsafe_get(), mBufferQueue.size());
569765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else {
569885ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                ALOGW("OutputTrack::write() %p thread %p no more overflow buffers",
569985ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                        mThread.unsafe_get(), this);
570065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
570165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
570265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
570365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
570465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // Calling write() with a 0 length buffer, means that no more data will be written:
570565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // If no more buffers are pending, fill output track buffer to make sure it is started
570665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // by output mixer.
570765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (frames == 0 && mBufferQueue.size() == 0) {
570865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mCblk->user < mCblk->frameCount) {
570965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            frames = mCblk->frameCount - mCblk->user;
571065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            pInBuffer = new Buffer;
571165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            pInBuffer->mBuffer = new int16_t[frames * channelCount];
571265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            pInBuffer->frameCount = frames;
571365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            pInBuffer->i16 = pInBuffer->mBuffer;
571465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            memset(pInBuffer->raw, 0, frames * channelCount * sizeof(int16_t));
571565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mBufferQueue.add(pInBuffer);
571665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else if (mActive) {
571765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            stop();
571865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
571965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
572065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
572165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return outputBufferFull;
572265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
572365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
572485ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kastenstatus_t AudioFlinger::PlaybackThread::OutputTrack::obtainBuffer(
572585ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten        AudioBufferProvider::Buffer* buffer, uint32_t waitTimeMs)
572665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
572765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int active;
572865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t result;
572965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    audio_track_cblk_t* cblk = mCblk;
573065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    uint32_t framesReq = buffer->frameCount;
573165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
573226dd66e8ea7a1abf28c33196fc77822f68a718afGlenn Kasten    ALOGVV("OutputTrack::obtainBuffer user %d, server %d", cblk->user, cblk->server);
573365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    buffer->frameCount  = 0;
573465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5735864585df53eb97c31e77b3ad7c0d89e4f9b42588Glenn Kasten    uint32_t framesAvail = cblk->framesAvailableOut();
573665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
573765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
573865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (framesAvail == 0) {
573965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock _l(cblk->lock);
574065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        goto start_loop_here;
574165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        while (framesAvail == 0) {
574265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            active = mActive;
5743f6b1678f8f508b447155a81b44e214475ab634a8Glenn Kasten            if (CC_UNLIKELY(!active)) {
57443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("Not active and NO_MORE_BUFFERS");
5745335787fe43596f38ea2fa50b24c54d0823a3fb1dGlenn Kasten                return NO_MORE_BUFFERS;
574665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
574765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs));
574865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (result != NO_ERROR) {
5749335787fe43596f38ea2fa50b24c54d0823a3fb1dGlenn Kasten                return NO_MORE_BUFFERS;
575065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
575165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // read the server count again
575265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        start_loop_here:
5753864585df53eb97c31e77b3ad7c0d89e4f9b42588Glenn Kasten            framesAvail = cblk->framesAvailableOut_l();
575465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
575565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
575665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
575765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian//    if (framesAvail < framesReq) {
5758335787fe43596f38ea2fa50b24c54d0823a3fb1dGlenn Kasten//        return NO_MORE_BUFFERS;
575965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian//    }
576065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
576165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (framesReq > framesAvail) {
576265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        framesReq = framesAvail;
576365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
576465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
576565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    uint32_t u = cblk->user;
576665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    uint32_t bufferEnd = cblk->userBase + cblk->frameCount;
576765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5768a1472d9883e35edd280201c8be3191695007dfd4Marco Nelissen    if (framesReq > bufferEnd - u) {
576965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        framesReq = bufferEnd - u;
577065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
577165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
577265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    buffer->frameCount  = framesReq;
577383a0382dc17364567667a4e6135db43f5bd92efcGlenn Kasten    buffer->raw         = cblk->buffer(mBuffers, mFrameSize, u);
577465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
577565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
577665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
577765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
577865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::PlaybackThread::OutputTrack::clearBufferQueue()
577965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
578065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    size_t size = mBufferQueue.size();
578165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
578265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < size; i++) {
5783a111792f1314479c649d1d44c30c2caf70c00c2aGlenn Kasten        Buffer *pBuffer = mBufferQueue.itemAt(i);
578465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        delete [] pBuffer->mBuffer;
578565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        delete pBuffer;
578665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
578765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mBufferQueue.clear();
578865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
578965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
579065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
579165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
579265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid)
579365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    :   RefBase(),
579465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mAudioFlinger(audioFlinger),
579599e53b86eebb605b70dd7591b89bf61a9414ed0eGlenn Kasten        // FIXME should be a "k" constant not hard-coded, in .h or ro. property, see 4 lines below
579665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mMemoryDealer(new MemoryDealer(1024*1024, "AudioFlinger::Client")),
57974ff14bae91075eb274eb1c2975982358946e7e63John Grossman        mPid(pid),
57984ff14bae91075eb274eb1c2975982358946e7e63John Grossman        mTimedTrackCount(0)
579965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
580065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // 1 MB of address space is good for 32 tracks, 8 buffers each, 4 KB/buffer
580165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
580265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
580365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Client destructor must be called with AudioFlinger::mLock held
580465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::Client::~Client()
580565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
580665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mAudioFlinger->removeClient_l(mPid);
580765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
580865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5809435dbe6c3ecd04bcb4bd80584064e287ebccd720Glenn Kastensp<MemoryDealer> AudioFlinger::Client::heap() const
581065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
581165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mMemoryDealer;
581265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
581365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
58144ff14bae91075eb274eb1c2975982358946e7e63John Grossman// Reserve one of the limited slots for a timed audio track associated
58154ff14bae91075eb274eb1c2975982358946e7e63John Grossman// with this client
58164ff14bae91075eb274eb1c2975982358946e7e63John Grossmanbool AudioFlinger::Client::reserveTimedTrack()
58174ff14bae91075eb274eb1c2975982358946e7e63John Grossman{
58184ff14bae91075eb274eb1c2975982358946e7e63John Grossman    const int kMaxTimedTracksPerClient = 4;
58194ff14bae91075eb274eb1c2975982358946e7e63John Grossman
58204ff14bae91075eb274eb1c2975982358946e7e63John Grossman    Mutex::Autolock _l(mTimedTrackLock);
58214ff14bae91075eb274eb1c2975982358946e7e63John Grossman
58224ff14bae91075eb274eb1c2975982358946e7e63John Grossman    if (mTimedTrackCount >= kMaxTimedTracksPerClient) {
58234ff14bae91075eb274eb1c2975982358946e7e63John Grossman        ALOGW("can not create timed track - pid %d has exceeded the limit",
58244ff14bae91075eb274eb1c2975982358946e7e63John Grossman             mPid);
58254ff14bae91075eb274eb1c2975982358946e7e63John Grossman        return false;
58264ff14bae91075eb274eb1c2975982358946e7e63John Grossman    }
58274ff14bae91075eb274eb1c2975982358946e7e63John Grossman
58284ff14bae91075eb274eb1c2975982358946e7e63John Grossman    mTimedTrackCount++;
58294ff14bae91075eb274eb1c2975982358946e7e63John Grossman    return true;
58304ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
58314ff14bae91075eb274eb1c2975982358946e7e63John Grossman
58324ff14bae91075eb274eb1c2975982358946e7e63John Grossman// Release a slot for a timed audio track
58334ff14bae91075eb274eb1c2975982358946e7e63John Grossmanvoid AudioFlinger::Client::releaseTimedTrack()
58344ff14bae91075eb274eb1c2975982358946e7e63John Grossman{
58354ff14bae91075eb274eb1c2975982358946e7e63John Grossman    Mutex::Autolock _l(mTimedTrackLock);
58364ff14bae91075eb274eb1c2975982358946e7e63John Grossman    mTimedTrackCount--;
58374ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
58384ff14bae91075eb274eb1c2975982358946e7e63John Grossman
583965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
584065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
584165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::NotificationClient::NotificationClient(const sp<AudioFlinger>& audioFlinger,
584265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                                     const sp<IAudioFlingerClient>& client,
584365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                                     pid_t pid)
584484afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten    : mAudioFlinger(audioFlinger), mPid(pid), mAudioFlingerClient(client)
584565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
584665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
584765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
584865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::NotificationClient::~NotificationClient()
584965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
585065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
585165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
585265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::NotificationClient::binderDied(const wp<IBinder>& who)
585365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
585465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<NotificationClient> keep(this);
5855a111792f1314479c649d1d44c30c2caf70c00c2aGlenn Kasten    mAudioFlinger->removeNotificationClient(mPid);
585665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
585765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
585865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
585965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
586065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::TrackHandle::TrackHandle(const sp<AudioFlinger::PlaybackThread::Track>& track)
586165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    : BnAudioTrack(),
586265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mTrack(track)
586365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
586465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
586565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
586665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::TrackHandle::~TrackHandle() {
586765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // just stop the track on deletion, associated resources
586865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // will be freed from the main thread once all pending buffers have
586965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // been played. Unless it's not in the active track list, in which
587065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // case we free everything now...
587165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mTrack->destroy();
587265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
587365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
587490716c5728b37637b2d0a730a721bfc9fad299e0Glenn Kastensp<IMemory> AudioFlinger::TrackHandle::getCblk() const {
587590716c5728b37637b2d0a730a721bfc9fad299e0Glenn Kasten    return mTrack->getCblk();
587690716c5728b37637b2d0a730a721bfc9fad299e0Glenn Kasten}
587790716c5728b37637b2d0a730a721bfc9fad299e0Glenn Kasten
58783acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kastenstatus_t AudioFlinger::TrackHandle::start() {
58793acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten    return mTrack->start();
588065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
588165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
588265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::TrackHandle::stop() {
588365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mTrack->stop();
588465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
588565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
588665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::TrackHandle::flush() {
588765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mTrack->flush();
588865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
588965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
589065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::TrackHandle::mute(bool e) {
589165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mTrack->mute(e);
589265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
589365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
589465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::TrackHandle::pause() {
589565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mTrack->pause();
589665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
589765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
589865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::TrackHandle::attachAuxEffect(int EffectId)
589965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
590065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mTrack->attachAuxEffect(EffectId);
590165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
590265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
59034ff14bae91075eb274eb1c2975982358946e7e63John Grossmanstatus_t AudioFlinger::TrackHandle::allocateTimedBuffer(size_t size,
59044ff14bae91075eb274eb1c2975982358946e7e63John Grossman                                                         sp<IMemory>* buffer) {
59054ff14bae91075eb274eb1c2975982358946e7e63John Grossman    if (!mTrack->isTimedTrack())
59064ff14bae91075eb274eb1c2975982358946e7e63John Grossman        return INVALID_OPERATION;
59074ff14bae91075eb274eb1c2975982358946e7e63John Grossman
59084ff14bae91075eb274eb1c2975982358946e7e63John Grossman    PlaybackThread::TimedTrack* tt =
59094ff14bae91075eb274eb1c2975982358946e7e63John Grossman            reinterpret_cast<PlaybackThread::TimedTrack*>(mTrack.get());
59104ff14bae91075eb274eb1c2975982358946e7e63John Grossman    return tt->allocateTimedBuffer(size, buffer);
59114ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
59124ff14bae91075eb274eb1c2975982358946e7e63John Grossman
59134ff14bae91075eb274eb1c2975982358946e7e63John Grossmanstatus_t AudioFlinger::TrackHandle::queueTimedBuffer(const sp<IMemory>& buffer,
59144ff14bae91075eb274eb1c2975982358946e7e63John Grossman                                                     int64_t pts) {
59154ff14bae91075eb274eb1c2975982358946e7e63John Grossman    if (!mTrack->isTimedTrack())
59164ff14bae91075eb274eb1c2975982358946e7e63John Grossman        return INVALID_OPERATION;
59174ff14bae91075eb274eb1c2975982358946e7e63John Grossman
59184ff14bae91075eb274eb1c2975982358946e7e63John Grossman    PlaybackThread::TimedTrack* tt =
59194ff14bae91075eb274eb1c2975982358946e7e63John Grossman            reinterpret_cast<PlaybackThread::TimedTrack*>(mTrack.get());
59204ff14bae91075eb274eb1c2975982358946e7e63John Grossman    return tt->queueTimedBuffer(buffer, pts);
59214ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
59224ff14bae91075eb274eb1c2975982358946e7e63John Grossman
59234ff14bae91075eb274eb1c2975982358946e7e63John Grossmanstatus_t AudioFlinger::TrackHandle::setMediaTimeTransform(
59244ff14bae91075eb274eb1c2975982358946e7e63John Grossman    const LinearTransform& xform, int target) {
59254ff14bae91075eb274eb1c2975982358946e7e63John Grossman
59264ff14bae91075eb274eb1c2975982358946e7e63John Grossman    if (!mTrack->isTimedTrack())
59274ff14bae91075eb274eb1c2975982358946e7e63John Grossman        return INVALID_OPERATION;
59284ff14bae91075eb274eb1c2975982358946e7e63John Grossman
59294ff14bae91075eb274eb1c2975982358946e7e63John Grossman    PlaybackThread::TimedTrack* tt =
59304ff14bae91075eb274eb1c2975982358946e7e63John Grossman            reinterpret_cast<PlaybackThread::TimedTrack*>(mTrack.get());
59314ff14bae91075eb274eb1c2975982358946e7e63John Grossman    return tt->setMediaTimeTransform(
59324ff14bae91075eb274eb1c2975982358946e7e63John Grossman        xform, static_cast<TimedAudioTrack::TargetTimeline>(target));
59334ff14bae91075eb274eb1c2975982358946e7e63John Grossman}
59344ff14bae91075eb274eb1c2975982358946e7e63John Grossman
593565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::TrackHandle::onTransact(
593665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
593765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
593865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return BnAudioTrack::onTransact(code, data, reply, flags);
593965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
594065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
594165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
594265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
594365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansp<IAudioRecord> AudioFlinger::openRecord(
594465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        pid_t pid,
594572ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten        audio_io_handle_t input,
594665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        uint32_t sampleRate,
594758f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten        audio_format_t format,
5948254af180475346b6186b49c297f340c9c4817511Glenn Kasten        audio_channel_mask_t channelMask,
5949e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten        size_t frameCount,
5950a075db4ff9b086ac2885df77bb6da0869293df92Glenn Kasten        IAudioFlinger::track_flags_t flags,
59511879fff068422852c1483dcf8365c2ff0e2fadfcGlenn Kasten        pid_t tid,
595265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int *sessionId,
595365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status_t *status)
595465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
595565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<RecordThread::RecordTrack> recordTrack;
595665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<RecordHandle> recordHandle;
595765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<Client> client;
595865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t lStatus;
595965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    RecordThread *thread;
596065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    size_t inFrameCount;
596165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int lSessionId;
596265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
596365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check calling permissions
596465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!recordingAllowed()) {
596565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        lStatus = PERMISSION_DENIED;
596665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        goto Exit;
596765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
596865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
596965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // add client to list
597065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    { // scope for mLock
597165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock _l(mLock);
597265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        thread = checkRecordThread_l(input);
597365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (thread == NULL) {
597465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            lStatus = BAD_VALUE;
597565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            goto Exit;
597665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
597765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
597898ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten        client = registerPid_l(pid);
597965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
598065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // If no audio session id is provided, create one here
5981fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        if (sessionId != NULL && *sessionId != AUDIO_SESSION_OUTPUT_MIX) {
598265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            lSessionId = *sessionId;
598365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
59847c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            lSessionId = nextUniqueId();
598565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (sessionId != NULL) {
598665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                *sessionId = lSessionId;
598765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
598865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
598985ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten        // create new record track.
599085ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten        // The record track uses one track in mHardwareMixerThread by convention.
59911879fff068422852c1483dcf8365c2ff0e2fadfcGlenn Kasten        recordTrack = thread->createRecordTrack_l(client, sampleRate, format, channelMask,
59921879fff068422852c1483dcf8365c2ff0e2fadfcGlenn Kasten                                                  frameCount, lSessionId, flags, tid, &lStatus);
59937c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
59947c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (lStatus != NO_ERROR) {
599585ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten        // remove local strong reference to Client before deleting the RecordTrack so that the
599685ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten        // Client destructor is called by the TrackBase destructor with mLock held
599765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        client.clear();
599865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        recordTrack.clear();
599965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        goto Exit;
600065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
600165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
600265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // return to handle to client
600365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    recordHandle = new RecordHandle(recordTrack);
600465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    lStatus = NO_ERROR;
600565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
600665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianExit:
600765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (status) {
600865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        *status = lStatus;
600965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
601065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return recordHandle;
601165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
601265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
601365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
601465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
601585ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn KastenAudioFlinger::RecordHandle::RecordHandle(
601685ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten        const sp<AudioFlinger::RecordThread::RecordTrack>& recordTrack)
601765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    : BnAudioRecord(),
601865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mRecordTrack(recordTrack)
601965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
602065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
602165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
602265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::RecordHandle::~RecordHandle() {
6023d96c5724818fb47917bb5e7abe37799735e1ec0eGlenn Kasten    stop_nonvirtual();
6024510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    mRecordTrack->destroy();
602565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
602665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
602790716c5728b37637b2d0a730a721bfc9fad299e0Glenn Kastensp<IMemory> AudioFlinger::RecordHandle::getCblk() const {
602890716c5728b37637b2d0a730a721bfc9fad299e0Glenn Kasten    return mRecordTrack->getCblk();
602990716c5728b37637b2d0a730a721bfc9fad299e0Glenn Kasten}
603090716c5728b37637b2d0a730a721bfc9fad299e0Glenn Kasten
603185ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kastenstatus_t AudioFlinger::RecordHandle::start(int /*AudioSystem::sync_event_t*/ event,
603285ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten        int triggerSession) {
60333856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("RecordHandle::start()");
60343acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten    return mRecordTrack->start((AudioSystem::sync_event_t)event, triggerSession);
603565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
603665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
603765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::RecordHandle::stop() {
6038d96c5724818fb47917bb5e7abe37799735e1ec0eGlenn Kasten    stop_nonvirtual();
6039d96c5724818fb47917bb5e7abe37799735e1ec0eGlenn Kasten}
6040d96c5724818fb47917bb5e7abe37799735e1ec0eGlenn Kasten
6041d96c5724818fb47917bb5e7abe37799735e1ec0eGlenn Kastenvoid AudioFlinger::RecordHandle::stop_nonvirtual() {
60423856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("RecordHandle::stop()");
604365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mRecordTrack->stop();
604465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
604565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
604665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::RecordHandle::onTransact(
604765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
604865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
604965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return BnAudioRecord::onTransact(code, data, reply, flags);
605065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
605165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
605265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
605365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
60547c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric LaurentAudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger,
60557c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                         AudioStreamIn *input,
60567c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                         uint32_t sampleRate,
6057254af180475346b6186b49c297f340c9c4817511Glenn Kasten                                         audio_channel_mask_t channelMask,
605872ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten                                         audio_io_handle_t id,
6059d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten                                         audio_devices_t device,
6060d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten                                         const sp<NBAIO_Sink>& teeSink) :
6061f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent    ThreadBase(audioFlinger, id, AUDIO_DEVICE_NONE, device, RECORD),
6062510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    mInput(input), mResampler(NULL), mRsmpOutBuffer(NULL), mRsmpInBuffer(NULL),
606384afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten    // mRsmpInIndex and mInputBytes set by readInputParameters()
6064254af180475346b6186b49c297f340c9c4817511Glenn Kasten    mReqChannelCount(popcount(channelMask)),
6065d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten    mReqSampleRate(sampleRate),
606684afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten    // mBytesRead is only meaningful while active, and so is cleared in start()
606784afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten    // (but might be better to also clear here for dump?)
6068d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten    mTeeSink(teeSink)
606965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
6070480b46802bef1371d5caa16ad5454fce04769c57Glenn Kasten    snprintf(mName, kNameLength, "AudioIn_%X", id);
6071feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
607265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    readInputParameters();
6073d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten
607465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
607565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
607665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
607765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::RecordThread::~RecordThread()
607865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
607965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    delete[] mRsmpInBuffer;
6080e9dd0176933d6233916c84e18f3e8c0d644ca05dGlenn Kasten    delete mResampler;
6081e9dd0176933d6233916c84e18f3e8c0d644ca05dGlenn Kasten    delete[] mRsmpOutBuffer;
608265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
608365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
608465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::RecordThread::onFirstRef()
608565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
6086feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    run(mName, PRIORITY_URGENT_AUDIO);
608765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
608865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6089b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurentstatus_t AudioFlinger::RecordThread::readyToRun()
6090b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent{
6091b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    status_t status = initCheck();
60925ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block    ALOGW_IF(status != NO_ERROR,"RecordThread %p could not initialize", this);
6093b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    return status;
6094b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent}
6095b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
609665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool AudioFlinger::RecordThread::threadLoop()
609765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
609865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    AudioBufferProvider::Buffer buffer;
609965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<RecordTrack> activeTrack;
61007c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    Vector< sp<EffectChain> > effectChains;
610165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
610244d9848d6656777a18019223e0d35f2fcc67719aEric Laurent    nsecs_t lastWarning = 0;
610344d9848d6656777a18019223e0d35f2fcc67719aEric Laurent
6104e4e2a37dbe2a4d923232305549101f779a2e3638Glenn Kasten    inputStandBy();
6105feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    acquireWakeLock();
6106feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
61074362f5300162ed55f56cf167eccf7f2e5b89d435Jean-Michel Trivi    // used to verify we've read at least once before evaluating how many bytes were read
610852762410dbc9189cd92a4094a1dbd4cfe8e71cb6Jean-Michel Trivi    bool readOnce = false;
610952762410dbc9189cd92a4094a1dbd4cfe8e71cb6Jean-Michel Trivi
611065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // start recording
611165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    while (!exitPending()) {
611265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
611365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        processConfigEvents();
611465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
611565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        { // scope for mLock
611665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            Mutex::Autolock _l(mLock);
611765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            checkForNewParameters_l();
611865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (mActiveTrack == 0 && mConfigEvents.isEmpty()) {
6119e4e2a37dbe2a4d923232305549101f779a2e3638Glenn Kasten                standby();
612065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6121d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten                if (exitPending()) {
6122d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten                    break;
6123d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten                }
612465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6125feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent                releaseWakeLock_l();
61263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("RecordThread: loop stopping");
612765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // go to sleep
612865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mWaitWorkCV.wait(mLock);
61293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("RecordThread: loop starting");
6130feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent                acquireWakeLock_l();
613165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                continue;
613265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
613365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (mActiveTrack != 0) {
613465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (mActiveTrack->mState == TrackBase::PAUSING) {
6135e4e2a37dbe2a4d923232305549101f779a2e3638Glenn Kasten                    standby();
613665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mActiveTrack.clear();
613765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mStartStopCond.broadcast();
613865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                } else if (mActiveTrack->mState == TrackBase::RESUMING) {
613965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    if (mReqChannelCount != mActiveTrack->channelCount()) {
614065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        mActiveTrack.clear();
614165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        mStartStopCond.broadcast();
614252762410dbc9189cd92a4094a1dbd4cfe8e71cb6Jean-Michel Trivi                    } else if (readOnce) {
614365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        // record start succeeds only if first read from audio input
614465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        // succeeds
614552762410dbc9189cd92a4094a1dbd4cfe8e71cb6Jean-Michel Trivi                        if (mBytesRead >= 0) {
614665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            mActiveTrack->mState = TrackBase::ACTIVE;
614765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        } else {
614865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            mActiveTrack.clear();
614965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        }
615065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        mStartStopCond.broadcast();
615165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    }
615265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mStandby = false;
6153510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                } else if (mActiveTrack->mState == TrackBase::TERMINATED) {
6154510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                    removeTrack_l(mActiveTrack);
6155510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                    mActiveTrack.clear();
615665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
615765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
61587c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            lockEffectChains_l(effectChains);
615965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
616065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
616165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mActiveTrack != 0) {
616265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (mActiveTrack->mState != TrackBase::ACTIVE &&
616365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mActiveTrack->mState != TrackBase::RESUMING) {
61647c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                unlockEffectChains(effectChains);
61657c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                usleep(kRecordThreadSleepUs);
616665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                continue;
616765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
61687c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            for (size_t i = 0; i < effectChains.size(); i ++) {
61697c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                effectChains[i]->process_l();
61707c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            }
61717c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
617265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            buffer.frameCount = mFrameCount;
617301c4ebf6b794493898114a502ed36de13137f7e5Glenn Kasten            if (CC_LIKELY(mActiveTrack->getNextBuffer(&buffer) == NO_ERROR)) {
617452762410dbc9189cd92a4094a1dbd4cfe8e71cb6Jean-Michel Trivi                readOnce = true;
617565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                size_t framesOut = buffer.frameCount;
6176e0feee3da22beeffbd9357540e265f13b2119cbbGlenn Kasten                if (mResampler == NULL) {
617765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    // no resampling
617865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    while (framesOut) {
617965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        size_t framesIn = mFrameCount - mRsmpInIndex;
618065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        if (framesIn) {
618165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            int8_t *src = (int8_t *)mRsmpInBuffer + mRsmpInIndex * mFrameSize;
618285ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                            int8_t *dst = buffer.i8 + (buffer.frameCount - framesOut) *
618383a0382dc17364567667a4e6135db43f5bd92efcGlenn Kasten                                    mActiveTrack->mFrameSize;
618465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            if (framesIn > framesOut)
618565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                framesIn = framesOut;
618665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            mRsmpInIndex += framesIn;
618765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            framesOut -= framesIn;
618865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            if ((int)mChannelCount == mReqChannelCount ||
6189fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                mFormat != AUDIO_FORMAT_PCM_16_BIT) {
619065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                memcpy(dst, src, framesIn * mFrameSize);
619165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            } else {
619265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                if (mChannelCount == 1) {
619369d799679c8c0308e42057e7b5ad63a7ae806480Glenn Kasten                                    upmix_to_stereo_i16_from_mono_i16((int16_t *)dst,
619469d799679c8c0308e42057e7b5ad63a7ae806480Glenn Kasten                                            (int16_t *)src, framesIn);
619565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                } else {
619669d799679c8c0308e42057e7b5ad63a7ae806480Glenn Kasten                                    downmix_to_mono_i16_from_stereo_i16((int16_t *)dst,
619769d799679c8c0308e42057e7b5ad63a7ae806480Glenn Kasten                                            (int16_t *)src, framesIn);
619865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                }
619965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            }
620065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        }
620165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        if (framesOut && mFrameCount == mRsmpInIndex) {
6202d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten                            void *readInto;
620365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            if (framesOut == mFrameCount &&
620485ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                                ((int)mChannelCount == mReqChannelCount ||
620585ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                                        mFormat != AUDIO_FORMAT_PCM_16_BIT)) {
6206d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten                                readInto = buffer.raw;
620765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                framesOut = 0;
620865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            } else {
6209d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten                                readInto = mRsmpInBuffer;
621065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                mRsmpInIndex = 0;
621165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            }
6212d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten                            mBytesRead = mInput->stream->read(mInput->stream, readInto, mInputBytes);
621352762410dbc9189cd92a4094a1dbd4cfe8e71cb6Jean-Michel Trivi                            if (mBytesRead <= 0) {
621452762410dbc9189cd92a4094a1dbd4cfe8e71cb6Jean-Michel Trivi                                if ((mBytesRead < 0) && (mActiveTrack->mState == TrackBase::ACTIVE))
621552762410dbc9189cd92a4094a1dbd4cfe8e71cb6Jean-Michel Trivi                                {
621652762410dbc9189cd92a4094a1dbd4cfe8e71cb6Jean-Michel Trivi                                    ALOGE("Error reading audio input");
621765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                    // Force input into standby so that it tries to
621865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                    // recover at next read attempt
6219e4e2a37dbe2a4d923232305549101f779a2e3638Glenn Kasten                                    inputStandBy();
62207c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                    usleep(kRecordThreadSleepUs);
622165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                }
622265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                mRsmpInIndex = mFrameCount;
622365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                framesOut = 0;
622465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                buffer.frameCount = 0;
6225d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten                            } else if (mTeeSink != 0) {
6226d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten                                (void) mTeeSink->write(readInto,
6227d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten                                        mBytesRead >> Format_frameBitShift(mTeeSink->format()));
622865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            }
622965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        }
623065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    }
623165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                } else {
623265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    // resampling
623365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
623465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    memset(mRsmpOutBuffer, 0, framesOut * 2 * sizeof(int32_t));
623565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    // alter output frame count as if we were expecting stereo samples
623665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    if (mChannelCount == 1 && mReqChannelCount == 1) {
623765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        framesOut >>= 1;
623865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    }
623985ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                    mResampler->resample(mRsmpOutBuffer, framesOut,
624085ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                            this /* AudioBufferProvider* */);
624185ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                    // ditherAndClamp() works as long as all buffers returned by
624285ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                    // mActiveTrack->getNextBuffer() are 32 bit aligned which should be always true.
624365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    if (mChannelCount == 2 && mReqChannelCount == 1) {
62443b21c50ef95fe4e7ac3426ca14b365749e66ff08Glenn Kasten                        ditherAndClamp(mRsmpOutBuffer, mRsmpOutBuffer, framesOut);
624585ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                        // the resampler always outputs stereo samples:
624685ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                        // do post stereo to mono conversion
624769d799679c8c0308e42057e7b5ad63a7ae806480Glenn Kasten                        downmix_to_mono_i16_from_stereo_i16(buffer.i16, (int16_t *)mRsmpOutBuffer,
624869d799679c8c0308e42057e7b5ad63a7ae806480Glenn Kasten                                framesOut);
624965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    } else {
62503b21c50ef95fe4e7ac3426ca14b365749e66ff08Glenn Kasten                        ditherAndClamp((int32_t *)buffer.raw, mRsmpOutBuffer, framesOut);
625165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    }
625265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
625365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
6254a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                if (mFramestoDrop == 0) {
6255a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                    mActiveTrack->releaseBuffer(&buffer);
6256a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                } else {
6257a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                    if (mFramestoDrop > 0) {
6258a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                        mFramestoDrop -= buffer.frameCount;
62592986460984580833161bdaabc7f17da1005a8961Eric Laurent                        if (mFramestoDrop <= 0) {
62602986460984580833161bdaabc7f17da1005a8961Eric Laurent                            clearSyncStartEvent();
62612986460984580833161bdaabc7f17da1005a8961Eric Laurent                        }
62622986460984580833161bdaabc7f17da1005a8961Eric Laurent                    } else {
62632986460984580833161bdaabc7f17da1005a8961Eric Laurent                        mFramestoDrop += buffer.frameCount;
62642986460984580833161bdaabc7f17da1005a8961Eric Laurent                        if (mFramestoDrop >= 0 || mSyncStartEvent == 0 ||
62652986460984580833161bdaabc7f17da1005a8961Eric Laurent                                mSyncStartEvent->isCancelled()) {
62662986460984580833161bdaabc7f17da1005a8961Eric Laurent                            ALOGW("Synced record %s, session %d, trigger session %d",
62672986460984580833161bdaabc7f17da1005a8961Eric Laurent                                  (mFramestoDrop >= 0) ? "timed out" : "cancelled",
62682986460984580833161bdaabc7f17da1005a8961Eric Laurent                                  mActiveTrack->sessionId(),
62692986460984580833161bdaabc7f17da1005a8961Eric Laurent                                  (mSyncStartEvent != 0) ? mSyncStartEvent->triggerSession() : 0);
62702986460984580833161bdaabc7f17da1005a8961Eric Laurent                            clearSyncStartEvent();
6271a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                        }
6272a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                    }
6273a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                }
627404270daf50f0c602d7c57a257a693e68246cbeb7Glenn Kasten                mActiveTrack->clearOverflow();
627565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
627665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // client isn't retrieving buffers fast enough
627765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            else {
627844d9848d6656777a18019223e0d35f2fcc67719aEric Laurent                if (!mActiveTrack->setOverflow()) {
627944d9848d6656777a18019223e0d35f2fcc67719aEric Laurent                    nsecs_t now = systemTime();
62807dede876998ff56351d495ec3a798c1b131193e8Glenn Kasten                    if ((now - lastWarning) > kWarningThrottleNs) {
62815ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block                        ALOGW("RecordThread: buffer overflow");
628244d9848d6656777a18019223e0d35f2fcc67719aEric Laurent                        lastWarning = now;
628344d9848d6656777a18019223e0d35f2fcc67719aEric Laurent                    }
628444d9848d6656777a18019223e0d35f2fcc67719aEric Laurent                }
628565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // Release the processor for a while before asking for a new buffer.
628665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // This will give the application more chance to read from the buffer and
628765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // clear the overflow.
62887c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                usleep(kRecordThreadSleepUs);
628965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
629065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
6291ec437d8d3db79459d7b19e1734e6fe309bd621e8Eric Laurent        // enable changes in effect chain
6292ec437d8d3db79459d7b19e1734e6fe309bd621e8Eric Laurent        unlockEffectChains(effectChains);
62937c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        effectChains.clear();
629465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
629565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6296e4e2a37dbe2a4d923232305549101f779a2e3638Glenn Kasten    standby();
629765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
629833e6e35b03a726e35203e97550f32154c91d5f13Glenn Kasten    {
629933e6e35b03a726e35203e97550f32154c91d5f13Glenn Kasten        Mutex::Autolock _l(mLock);
630033e6e35b03a726e35203e97550f32154c91d5f13Glenn Kasten        mActiveTrack.clear();
630133e6e35b03a726e35203e97550f32154c91d5f13Glenn Kasten        mStartStopCond.broadcast();
630233e6e35b03a726e35203e97550f32154c91d5f13Glenn Kasten    }
630365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6304feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent    releaseWakeLock();
6305feb0db689c17dced50afaee54c659f1676e2d505Eric Laurent
63063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("RecordThread %p exiting", this);
630765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return false;
630865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
630965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6310e4e2a37dbe2a4d923232305549101f779a2e3638Glenn Kastenvoid AudioFlinger::RecordThread::standby()
6311e4e2a37dbe2a4d923232305549101f779a2e3638Glenn Kasten{
6312e4e2a37dbe2a4d923232305549101f779a2e3638Glenn Kasten    if (!mStandby) {
6313e4e2a37dbe2a4d923232305549101f779a2e3638Glenn Kasten        inputStandBy();
6314e4e2a37dbe2a4d923232305549101f779a2e3638Glenn Kasten        mStandby = true;
6315e4e2a37dbe2a4d923232305549101f779a2e3638Glenn Kasten    }
6316e4e2a37dbe2a4d923232305549101f779a2e3638Glenn Kasten}
6317e4e2a37dbe2a4d923232305549101f779a2e3638Glenn Kasten
6318e4e2a37dbe2a4d923232305549101f779a2e3638Glenn Kastenvoid AudioFlinger::RecordThread::inputStandBy()
6319e4e2a37dbe2a4d923232305549101f779a2e3638Glenn Kasten{
6320e4e2a37dbe2a4d923232305549101f779a2e3638Glenn Kasten    mInput->stream->common.standby(&mInput->stream->common);
6321e4e2a37dbe2a4d923232305549101f779a2e3638Glenn Kasten}
63227c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
63237c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurentsp<AudioFlinger::RecordThread::RecordTrack>  AudioFlinger::RecordThread::createRecordTrack_l(
63247c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        const sp<AudioFlinger::Client>& client,
63257c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        uint32_t sampleRate,
632658f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten        audio_format_t format,
6327254af180475346b6186b49c297f340c9c4817511Glenn Kasten        audio_channel_mask_t channelMask,
6328e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kasten        size_t frameCount,
63297c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        int sessionId,
63301879fff068422852c1483dcf8365c2ff0e2fadfcGlenn Kasten        IAudioFlinger::track_flags_t flags,
63311879fff068422852c1483dcf8365c2ff0e2fadfcGlenn Kasten        pid_t tid,
63327c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        status_t *status)
63337c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent{
63347c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    sp<RecordTrack> track;
63357c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    status_t lStatus;
63367c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
63377c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    lStatus = initCheck();
63387c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (lStatus != NO_ERROR) {
633929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Audio driver not initialized.");
63407c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        goto Exit;
63417c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
63427c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
63431879fff068422852c1483dcf8365c2ff0e2fadfcGlenn Kasten    // FIXME use flags and tid similar to createTrack_l()
63441879fff068422852c1483dcf8365c2ff0e2fadfcGlenn Kasten
63457c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    { // scope for mLock
63467c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        Mutex::Autolock _l(mLock);
63477c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
63487c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        track = new RecordTrack(this, client, sampleRate,
63495cf034d92d901169ca6e36c90475f40715827fcdGlenn Kasten                      format, channelMask, frameCount, sessionId);
63507c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
63517378ca506e4e20c2b2d4e94a131cf1b95831adb5Glenn Kasten        if (track->getCblk() == 0) {
63527c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            lStatus = NO_MEMORY;
63537c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            goto Exit;
63547c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        }
6355510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten        mTracks.add(track);
63567c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
635759bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent        // disable AEC and NS if the device is a BT SCO headset supporting those pre processings
6358f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent        bool suspend = audio_is_bluetooth_sco_device(mInDevice) &&
6359bb4350d3b9e9485ae59e084de270f86aecef8066Glenn Kasten                        mAudioFlinger->btNrecIsOff();
636059bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent        setEffectSuspended_l(FX_IID_AEC, suspend, sessionId);
636159bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent        setEffectSuspended_l(FX_IID_NS, suspend, sessionId);
63627c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
63637c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    lStatus = NO_ERROR;
63647c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
63657c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric LaurentExit:
63667c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (status) {
63677c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        *status = lStatus;
63687c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
63697c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    return track;
63707c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent}
63717c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
6372a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurentstatus_t AudioFlinger::RecordThread::start(RecordThread::RecordTrack* recordTrack,
63733acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten                                           AudioSystem::sync_event_t event,
6374a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                                           int triggerSession)
637565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
637658912562617941964939a4182cda71eaeb153d4bGlenn Kasten    ALOGV("RecordThread::start event %d, triggerSession %d", event, triggerSession);
6377e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    sp<ThreadBase> strongMe = this;
637865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t status = NO_ERROR;
6379a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
6380a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    if (event == AudioSystem::SYNC_EVENT_NONE) {
63812986460984580833161bdaabc7f17da1005a8961Eric Laurent        clearSyncStartEvent();
6382a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    } else if (event != AudioSystem::SYNC_EVENT_SAME) {
6383a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        mSyncStartEvent = mAudioFlinger->createSyncEvent(event,
6384a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                                       triggerSession,
6385a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                                       recordTrack->sessionId(),
6386a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                                       syncStartEventCallback,
6387a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                                       this);
63882986460984580833161bdaabc7f17da1005a8961Eric Laurent        // Sync event can be cancelled by the trigger session if the track is not in a
63892986460984580833161bdaabc7f17da1005a8961Eric Laurent        // compatible state in which case we start record immediately
63902986460984580833161bdaabc7f17da1005a8961Eric Laurent        if (mSyncStartEvent->isCancelled()) {
63912986460984580833161bdaabc7f17da1005a8961Eric Laurent            clearSyncStartEvent();
63922986460984580833161bdaabc7f17da1005a8961Eric Laurent        } else {
63932986460984580833161bdaabc7f17da1005a8961Eric Laurent            // do not wait for the event for more than AudioSystem::kSyncRecordStartTimeOutMs
63942986460984580833161bdaabc7f17da1005a8961Eric Laurent            mFramestoDrop = - ((AudioSystem::kSyncRecordStartTimeOutMs * mReqSampleRate) / 1000);
63952986460984580833161bdaabc7f17da1005a8961Eric Laurent        }
6396a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    }
6397a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
639865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    {
6399a7d8d6fc5e102a08b262a1b78aa1abeeb097d9e4Glenn Kasten        AutoMutex lock(mLock);
640065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mActiveTrack != 0) {
640165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (recordTrack != mActiveTrack.get()) {
640265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                status = -EBUSY;
640365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else if (mActiveTrack->mState == TrackBase::PAUSING) {
640465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mActiveTrack->mState = TrackBase::ACTIVE;
640565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
640665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return status;
640765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
640865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
640965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        recordTrack->mState = TrackBase::IDLE;
641065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mActiveTrack = recordTrack;
641165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mLock.unlock();
641265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status_t status = AudioSystem::startInput(mId);
641365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mLock.lock();
641465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (status != NO_ERROR) {
641565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mActiveTrack.clear();
6416a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent            clearSyncStartEvent();
641765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return status;
641865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
641965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mRsmpInIndex = mFrameCount;
642065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mBytesRead = 0;
6421243f5f91755c01614a8cafe90b0806396e22d553Eric Laurent        if (mResampler != NULL) {
6422243f5f91755c01614a8cafe90b0806396e22d553Eric Laurent            mResampler->reset();
6423243f5f91755c01614a8cafe90b0806396e22d553Eric Laurent        }
6424243f5f91755c01614a8cafe90b0806396e22d553Eric Laurent        mActiveTrack->mState = TrackBase::RESUMING;
642565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // signal thread to start
64263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Signal record thread");
6427b6ba2fd0d61a4844c153e17843fbe2c841c4bf57Eric Laurent        mWaitWorkCV.broadcast();
642865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // do not wait for mStartStopCond if exiting
6429b28686f95daee16edeb5f39af2cd5274ac3dc99fGlenn Kasten        if (exitPending()) {
643065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mActiveTrack.clear();
643165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            status = INVALID_OPERATION;
643265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            goto startError;
643365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
643465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mStartStopCond.wait(mLock);
643565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mActiveTrack == 0) {
64363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("Record failed to start");
643765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            status = BAD_VALUE;
643865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            goto startError;
643965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
64403856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Record started OK");
644165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return status;
644265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
644365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianstartError:
644465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    AudioSystem::stopInput(mId);
6445a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    clearSyncStartEvent();
644665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return status;
644765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
644865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6449a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurentvoid AudioFlinger::RecordThread::clearSyncStartEvent()
6450a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent{
6451a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    if (mSyncStartEvent != 0) {
6452a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        mSyncStartEvent->cancel();
6453a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    }
6454a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    mSyncStartEvent.clear();
64552986460984580833161bdaabc7f17da1005a8961Eric Laurent    mFramestoDrop = 0;
6456a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent}
6457a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
6458a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurentvoid AudioFlinger::RecordThread::syncStartEventCallback(const wp<SyncEvent>& event)
6459a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent{
6460a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    sp<SyncEvent> strongEvent = event.promote();
6461a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
6462a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    if (strongEvent != 0) {
6463a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        RecordThread *me = (RecordThread *)strongEvent->cookie();
6464a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        me->handleSyncStartEvent(strongEvent);
6465a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    }
6466a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent}
6467a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
6468a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurentvoid AudioFlinger::RecordThread::handleSyncStartEvent(const sp<SyncEvent>& event)
6469a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent{
64702986460984580833161bdaabc7f17da1005a8961Eric Laurent    if (event == mSyncStartEvent) {
6471a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        // TODO: use actual buffer filling status instead of 2 buffers when info is available
6472a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        // from audio HAL
6473a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        mFramestoDrop = mFrameCount * 2;
6474a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    }
6475a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent}
6476a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
64771d491ff06f4b9c90ff24fe953b90d0843eaf1c04Glenn Kastenbool AudioFlinger::RecordThread::stop_l(RecordThread::RecordTrack* recordTrack) {
64783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("RecordThread::stop");
64791d491ff06f4b9c90ff24fe953b90d0843eaf1c04Glenn Kasten    if (recordTrack != mActiveTrack.get() || recordTrack->mState == TrackBase::PAUSING) {
64801d491ff06f4b9c90ff24fe953b90d0843eaf1c04Glenn Kasten        return false;
64811d491ff06f4b9c90ff24fe953b90d0843eaf1c04Glenn Kasten    }
64821d491ff06f4b9c90ff24fe953b90d0843eaf1c04Glenn Kasten    recordTrack->mState = TrackBase::PAUSING;
64831d491ff06f4b9c90ff24fe953b90d0843eaf1c04Glenn Kasten    // do not wait for mStartStopCond if exiting
64841d491ff06f4b9c90ff24fe953b90d0843eaf1c04Glenn Kasten    if (exitPending()) {
64851d491ff06f4b9c90ff24fe953b90d0843eaf1c04Glenn Kasten        return true;
64861d491ff06f4b9c90ff24fe953b90d0843eaf1c04Glenn Kasten    }
64871d491ff06f4b9c90ff24fe953b90d0843eaf1c04Glenn Kasten    mStartStopCond.wait(mLock);
64881d491ff06f4b9c90ff24fe953b90d0843eaf1c04Glenn Kasten    // if we have been restarted, recordTrack == mActiveTrack.get() here
64891d491ff06f4b9c90ff24fe953b90d0843eaf1c04Glenn Kasten    if (exitPending() || recordTrack != mActiveTrack.get()) {
64901d491ff06f4b9c90ff24fe953b90d0843eaf1c04Glenn Kasten        ALOGV("Record stopped OK");
64911d491ff06f4b9c90ff24fe953b90d0843eaf1c04Glenn Kasten        return true;
649265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
64931d491ff06f4b9c90ff24fe953b90d0843eaf1c04Glenn Kasten    return false;
649465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
649565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6496106e8a42038f9e90d5ff97f8ab6f1a42258bde9eGlenn Kastenbool AudioFlinger::RecordThread::isValidSyncEvent(const sp<SyncEvent>& event) const
6497a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent{
6498a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    return false;
6499a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent}
6500a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
6501a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurentstatus_t AudioFlinger::RecordThread::setSyncEvent(const sp<SyncEvent>& event)
6502a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent{
65037aa25591769685ae0e8349b3ca3534c724484375Glenn Kasten#if 0   // This branch is currently dead code, but is preserved in case it will be needed in future
6504a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    if (!isValidSyncEvent(event)) {
6505a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        return BAD_VALUE;
6506a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    }
6507a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
6508510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    int eventSession = event->triggerSession();
6509510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    status_t ret = NAME_NOT_FOUND;
6510510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten
6511a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    Mutex::Autolock _l(mLock);
6512a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
6513510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    for (size_t i = 0; i < mTracks.size(); i++) {
6514510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten        sp<RecordTrack> track = mTracks[i];
6515510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten        if (eventSession == track->sessionId()) {
6516d23eedca9b5a1812891c05d89850ab7ee707040dGlenn Kasten            (void) track->setSyncEvent(event);
6517510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten            ret = NO_ERROR;
6518510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten        }
6519510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    }
6520510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    return ret;
65217aa25591769685ae0e8349b3ca3534c724484375Glenn Kasten#else
65227aa25591769685ae0e8349b3ca3534c724484375Glenn Kasten    return BAD_VALUE;
65237aa25591769685ae0e8349b3ca3534c724484375Glenn Kasten#endif
6524510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten}
6525510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten
6526510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kastenvoid AudioFlinger::RecordThread::RecordTrack::destroy()
6527510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten{
6528510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    // see comments at AudioFlinger::PlaybackThread::Track::destroy()
6529510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    sp<RecordTrack> keep(this);
6530510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    {
6531510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten        sp<ThreadBase> thread = mThread.promote();
6532510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten        if (thread != 0) {
6533510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten            if (mState == ACTIVE || mState == RESUMING) {
6534510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                AudioSystem::stopInput(thread->id());
6535510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten            }
6536510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten            AudioSystem::releaseInput(thread->id());
6537510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten            Mutex::Autolock _l(thread->mLock);
6538510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten            RecordThread *recordThread = (RecordThread *) thread.get();
6539510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten            recordThread->destroyTrack_l(this);
6540510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten        }
6541a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    }
6542510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten}
6543510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten
6544510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten// destroyTrack_l() must be called with ThreadBase::mLock held
6545510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kastenvoid AudioFlinger::RecordThread::destroyTrack_l(const sp<RecordTrack>& track)
6546510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten{
6547510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    track->mState = TrackBase::TERMINATED;
6548510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    // active tracks are removed by threadLoop()
6549510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    if (mActiveTrack != track) {
6550510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten        removeTrack_l(track);
6551510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    }
6552510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten}
6553510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten
6554510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kastenvoid AudioFlinger::RecordThread::removeTrack_l(const sp<RecordTrack>& track)
6555510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten{
6556510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    mTracks.remove(track);
6557510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    // need anything related to effects here?
6558a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent}
6559a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
6560be5f05e0fdfc4e3799653702187861a2afa072eeGlenn Kastenvoid AudioFlinger::RecordThread::dump(int fd, const Vector<String16>& args)
656165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
6562510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    dumpInternals(fd, args);
6563510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    dumpTracks(fd, args);
6564510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    dumpEffectChains(fd, args);
6565510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten}
6566510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten
6567510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kastenvoid AudioFlinger::RecordThread::dumpInternals(int fd, const Vector<String16>& args)
6568510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten{
656965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
657065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
657165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
657265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
657365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "\nInput thread %p internals\n", this);
657465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
657565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
657665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mActiveTrack != 0) {
657765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        snprintf(buffer, SIZE, "In index: %d\n", mRsmpInIndex);
657865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        result.append(buffer);
657965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        snprintf(buffer, SIZE, "In size: %d\n", mInputBytes);
658065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        result.append(buffer);
6581e0feee3da22beeffbd9357540e265f13b2119cbbGlenn Kasten        snprintf(buffer, SIZE, "Resampling: %d\n", (mResampler != NULL));
658265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        result.append(buffer);
658365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        snprintf(buffer, SIZE, "Out channel count: %d\n", mReqChannelCount);
658465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        result.append(buffer);
65853b16c766d1ae2cfd8487e8ffb2b23936fc0a8e17Glenn Kasten        snprintf(buffer, SIZE, "Out sample rate: %u\n", mReqSampleRate);
658665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        result.append(buffer);
658765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
6588510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten        result.append("No active record client\n");
658965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
6590510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten
659165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
659265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
659365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    dumpBase(fd, args);
6594510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten}
6595510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten
6596510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kastenvoid AudioFlinger::RecordThread::dumpTracks(int fd, const Vector<String16>& args)
6597510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten{
6598510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    const size_t SIZE = 256;
6599510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    char buffer[SIZE];
6600510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    String8 result;
6601510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten
6602510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    snprintf(buffer, SIZE, "Input thread %p tracks\n", this);
6603510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    result.append(buffer);
6604510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    RecordTrack::appendDumpHeader(result);
6605510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    for (size_t i = 0; i < mTracks.size(); ++i) {
6606510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten        sp<RecordTrack> track = mTracks[i];
6607510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten        if (track != 0) {
6608510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten            track->dump(buffer, SIZE);
6609510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten            result.append(buffer);
6610510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten        }
6611510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    }
6612510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten
6613510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    if (mActiveTrack != 0) {
6614510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten        snprintf(buffer, SIZE, "\nInput thread %p active tracks\n", this);
6615510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten        result.append(buffer);
6616510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten        RecordTrack::appendDumpHeader(result);
6617510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten        mActiveTrack->dump(buffer, SIZE);
6618510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten        result.append(buffer);
6619510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten
6620510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    }
6621510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    write(fd, result.string(), result.size());
662265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
662365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
662401c4ebf6b794493898114a502ed36de13137f7e5Glenn Kasten// AudioBufferProvider interface
66254ff14bae91075eb274eb1c2975982358946e7e63John Grossmanstatus_t AudioFlinger::RecordThread::getNextBuffer(AudioBufferProvider::Buffer* buffer, int64_t pts)
662665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
662765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    size_t framesReq = buffer->frameCount;
662865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    size_t framesReady = mFrameCount - mRsmpInIndex;
662965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int channelCount;
663065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
663165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (framesReady == 0) {
6632799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        mBytesRead = mInput->stream->read(mInput->stream, mRsmpInBuffer, mInputBytes);
66334362f5300162ed55f56cf167eccf7f2e5b89d435Jean-Michel Trivi        if (mBytesRead <= 0) {
66344362f5300162ed55f56cf167eccf7f2e5b89d435Jean-Michel Trivi            if ((mBytesRead < 0) && (mActiveTrack->mState == TrackBase::ACTIVE)) {
66354362f5300162ed55f56cf167eccf7f2e5b89d435Jean-Michel Trivi                ALOGE("RecordThread::getNextBuffer() Error reading audio input");
663665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // Force input into standby so that it tries to
663765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // recover at next read attempt
6638e4e2a37dbe2a4d923232305549101f779a2e3638Glenn Kasten                inputStandBy();
66397c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                usleep(kRecordThreadSleepUs);
664065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
6641e0feee3da22beeffbd9357540e265f13b2119cbbGlenn Kasten            buffer->raw = NULL;
664265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            buffer->frameCount = 0;
664365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return NOT_ENOUGH_DATA;
664465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
664565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mRsmpInIndex = 0;
664665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        framesReady = mFrameCount;
664765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
664865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
664965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (framesReq > framesReady) {
665065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        framesReq = framesReady;
665165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
665265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
665365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mChannelCount == 1 && mReqChannelCount == 2) {
665465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        channelCount = 1;
665565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
665665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        channelCount = 2;
665765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
665865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    buffer->raw = mRsmpInBuffer + mRsmpInIndex * channelCount;
665965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    buffer->frameCount = framesReq;
666065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
666165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
666265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
666301c4ebf6b794493898114a502ed36de13137f7e5Glenn Kasten// AudioBufferProvider interface
666465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::RecordThread::releaseBuffer(AudioBufferProvider::Buffer* buffer)
666565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
666665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mRsmpInIndex += buffer->frameCount;
666765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    buffer->frameCount = 0;
666865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
666965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
667065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool AudioFlinger::RecordThread::checkForNewParameters_l()
667165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
667265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool reconfig = false;
667365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
667465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    while (!mNewParameters.isEmpty()) {
667565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status_t status = NO_ERROR;
667665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        String8 keyValuePair = mNewParameters[0];
667765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        AudioParameter param = AudioParameter(keyValuePair);
667865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int value;
667958f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten        audio_format_t reqFormat = mFormat;
66803b16c766d1ae2cfd8487e8ffb2b23936fc0a8e17Glenn Kasten        uint32_t reqSamplingRate = mReqSampleRate;
668165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int reqChannelCount = mReqChannelCount;
668265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
668365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (param.getInt(String8(AudioParameter::keySamplingRate), value) == NO_ERROR) {
668465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            reqSamplingRate = value;
668565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            reconfig = true;
668665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
668765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (param.getInt(String8(AudioParameter::keyFormat), value) == NO_ERROR) {
668858f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten            reqFormat = (audio_format_t) value;
668965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            reconfig = true;
669065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
669165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (param.getInt(String8(AudioParameter::keyChannels), value) == NO_ERROR) {
6692fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin            reqChannelCount = popcount(value);
669365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            reconfig = true;
669465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
669565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (param.getInt(String8(AudioParameter::keyFrameCount), value) == NO_ERROR) {
669665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // do not accept frame count changes if tracks are open as the track buffer
669799e53b86eebb605b70dd7591b89bf61a9414ed0eGlenn Kasten            // size depends on frame count and correct behavior would not be guaranteed
669865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // if frame count is changed after track creation
669965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (mActiveTrack != 0) {
670065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                status = INVALID_OPERATION;
670165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else {
670265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                reconfig = true;
670365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
670465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
67057c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        if (param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) {
67067c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            // forward device change to effects that have requested to be
67077c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            // aware of attached audio device.
67087c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            for (size_t i = 0; i < mEffectChains.size(); i++) {
67097c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                mEffectChains[i]->setDevice_l(value);
67107c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            }
6711f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent
67127c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            // store input device and output device but do not forward output device to audio HAL.
67137c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            // Note that status is ignored by the caller for output device
67147c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            // (see AudioFlinger::setParameters()
6715f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent            if (audio_is_output_devices(value)) {
6716f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent                mOutDevice = value;
67177c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                status = BAD_VALUE;
67187c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            } else {
6719f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent                mInDevice = value;
672085ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                // disable AEC and NS if the device is a BT SCO headset supporting those
672185ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                // pre processings
6722510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                if (mTracks.size() > 0) {
6723f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent                    bool suspend = audio_is_bluetooth_sco_device(mInDevice) &&
6724f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent                                        mAudioFlinger->btNrecIsOff();
6725510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                    for (size_t i = 0; i < mTracks.size(); i++) {
6726510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                        sp<RecordTrack> track = mTracks[i];
6727510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                        setEffectSuspended_l(FX_IID_AEC, suspend, track->sessionId());
6728510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                        setEffectSuspended_l(FX_IID_NS, suspend, track->sessionId());
6729510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten                    }
673059bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent                }
67317c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            }
67327c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        }
673357b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent        if (param.getInt(String8(AudioParameter::keyInputSource), value) == NO_ERROR &&
673457b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent                mAudioSource != (audio_source_t)value) {
673557b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent            // forward device change to effects that have requested to be
673657b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent            // aware of attached audio device.
673757b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent            for (size_t i = 0; i < mEffectChains.size(); i++) {
673857b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent                mEffectChains[i]->setAudioSource_l((audio_source_t)value);
673957b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent            }
674057b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent            mAudioSource = (audio_source_t)value;
674157b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent        }
674265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (status == NO_ERROR) {
674385ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten            status = mInput->stream->common.set_parameters(&mInput->stream->common,
674485ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                    keyValuePair.string());
674565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (status == INVALID_OPERATION) {
6746e4e2a37dbe2a4d923232305549101f779a2e3638Glenn Kasten                inputStandBy();
6747e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                status = mInput->stream->common.set_parameters(&mInput->stream->common,
6748e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                        keyValuePair.string());
674965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
675065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (reconfig) {
675165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (status == BAD_VALUE &&
6752799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin                    reqFormat == mInput->stream->common.get_format(&mInput->stream->common) &&
6753fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                    reqFormat == AUDIO_FORMAT_PCM_16_BIT &&
675485ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                    ((int)mInput->stream->common.get_sample_rate(&mInput->stream->common)
675585ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                            <= (2 * reqSamplingRate)) &&
675685ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                    popcount(mInput->stream->common.get_channels(&mInput->stream->common))
675785ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                            <= FCC_2 &&
675853d76dbe7c55821e89d9da02e7a563f7fb45de87Glenn Kasten                    (reqChannelCount <= FCC_2)) {
675965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    status = NO_ERROR;
676065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
676165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (status == NO_ERROR) {
676265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    readInputParameters();
6763896adcd3ae6a1c7010e526327eff54e16179987bEric Laurent                    sendIoConfigEvent_l(AudioSystem::INPUT_CONFIG_CHANGED);
676465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
676565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
676665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
676765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
676865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mNewParameters.removeAt(0);
676965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
677065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mParamStatus = status;
677165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mParamCond.signal();
677260cd0a0d488e604d27fc7dbb02b00348693dfde2Eric Laurent        // wait for condition with time out in case the thread calling ThreadBase::setParameters()
677360cd0a0d488e604d27fc7dbb02b00348693dfde2Eric Laurent        // already timed out waiting for the status and will never signal the condition.
67747dede876998ff56351d495ec3a798c1b131193e8Glenn Kasten        mWaitWorkCV.waitRelative(mLock, kSetParametersTimeoutNs);
677565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
677665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return reconfig;
677765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
677865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
677965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianString8 AudioFlinger::RecordThread::getParameters(const String8& keys)
678065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
6781fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    char *s;
6782b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    String8 out_s8 = String8();
6783b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
6784b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    Mutex::Autolock _l(mLock);
6785b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    if (initCheck() != NO_ERROR) {
6786b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent        return out_s8;
6787b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    }
6788fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
6789799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    s = mInput->stream->common.get_parameters(&mInput->stream->common, keys.string());
6790fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    out_s8 = String8(s);
6791fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    free(s);
6792fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return out_s8;
679365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
679465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
679565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::RecordThread::audioConfigChanged_l(int event, int param) {
679665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    AudioSystem::OutputDescriptor desc;
6797a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten    void *param2 = NULL;
679865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
679965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    switch (event) {
680065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    case AudioSystem::INPUT_OPENED:
680165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    case AudioSystem::INPUT_CONFIG_CHANGED:
68020d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi        desc.channels = mChannelMask;
680365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        desc.samplingRate = mSampleRate;
680465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        desc.format = mFormat;
680565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        desc.frameCount = mFrameCount;
680665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        desc.latency = 0;
680765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        param2 = &desc;
680865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        break;
680965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
681065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    case AudioSystem::INPUT_CLOSED:
681165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    default:
681265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        break;
681365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
681465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mAudioFlinger->audioConfigChanged_l(event, mId, param2);
681565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
681665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
681765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::RecordThread::readInputParameters()
681865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
6819e9dd0176933d6233916c84e18f3e8c0d644ca05dGlenn Kasten    delete mRsmpInBuffer;
6820e9dd0176933d6233916c84e18f3e8c0d644ca05dGlenn Kasten    // mRsmpInBuffer is always assigned a new[] below
6821e9dd0176933d6233916c84e18f3e8c0d644ca05dGlenn Kasten    delete mRsmpOutBuffer;
6822e9dd0176933d6233916c84e18f3e8c0d644ca05dGlenn Kasten    mRsmpOutBuffer = NULL;
6823e9dd0176933d6233916c84e18f3e8c0d644ca05dGlenn Kasten    delete mResampler;
6824e0feee3da22beeffbd9357540e265f13b2119cbbGlenn Kasten    mResampler = NULL;
682565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6826799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    mSampleRate = mInput->stream->common.get_sample_rate(&mInput->stream->common);
68270d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi    mChannelMask = mInput->stream->common.get_channels(&mInput->stream->common);
68280d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi    mChannelCount = (uint16_t)popcount(mChannelMask);
6829799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    mFormat = mInput->stream->common.get_format(&mInput->stream->common);
6830b9980659501d0428d65d8292f3c32da69d37fbd2Glenn Kasten    mFrameSize = audio_stream_frame_size(&mInput->stream->common);
6831799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    mInputBytes = mInput->stream->common.get_buffer_size(&mInput->stream->common);
683265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mFrameCount = mInputBytes / mFrameSize;
683358912562617941964939a4182cda71eaeb153d4bGlenn Kasten    mNormalFrameCount = mFrameCount; // not used by record, but used by input effects
683465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mRsmpInBuffer = new int16_t[mFrameCount * mChannelCount];
683565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
683653d76dbe7c55821e89d9da02e7a563f7fb45de87Glenn Kasten    if (mSampleRate != mReqSampleRate && mChannelCount <= FCC_2 && mReqChannelCount <= FCC_2)
683765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    {
683865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int channelCount;
6839e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        // optimization: if mono to mono, use the resampler in stereo to stereo mode to avoid
6840e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        // stereo to mono post process as the resampler always outputs stereo.
684165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mChannelCount == 1 && mReqChannelCount == 2) {
684265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            channelCount = 1;
684365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
684465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            channelCount = 2;
684565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
684665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mResampler = AudioResampler::create(16, channelCount, mReqSampleRate);
684765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mResampler->setSampleRate(mSampleRate);
684865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mResampler->setVolume(AudioMixer::UNITY_GAIN, AudioMixer::UNITY_GAIN);
684965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mRsmpOutBuffer = new int32_t[mFrameCount * 2];
685065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
685185ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten        // optmization: if mono to mono, alter input frame count as if we were inputing
685285ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten        // stereo samples
685365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mChannelCount == 1 && mReqChannelCount == 1) {
685465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mFrameCount >>= 1;
685565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
685665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
685765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
685865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mRsmpInIndex = mFrameCount;
685965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
686065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
686165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianunsigned int AudioFlinger::RecordThread::getInputFramesLost()
686265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
6863b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    Mutex::Autolock _l(mLock);
6864b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    if (initCheck() != NO_ERROR) {
6865b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent        return 0;
6866b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    }
6867b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
6868799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    return mInput->stream->get_input_frames_lost(mInput->stream);
686965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
687065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6871106e8a42038f9e90d5ff97f8ab6f1a42258bde9eGlenn Kastenuint32_t AudioFlinger::RecordThread::hasAudioSession(int sessionId) const
68727c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent{
68737c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    Mutex::Autolock _l(mLock);
68747c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    uint32_t result = 0;
68757c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (getEffectChain_l(sessionId) != 0) {
68767c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        result = EFFECT_SESSION;
68777c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
68787c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
6879510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    for (size_t i = 0; i < mTracks.size(); ++i) {
6880510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten        if (sessionId == mTracks[i]->sessionId()) {
6881510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten            result |= TRACK_SESSION;
6882510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten            break;
6883510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten        }
68847c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
68857c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
68867c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    return result;
68877c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent}
68887c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
6889106e8a42038f9e90d5ff97f8ab6f1a42258bde9eGlenn KastenKeyedVector<int, bool> AudioFlinger::RecordThread::sessionIds() const
689059bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent{
6891510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    KeyedVector<int, bool> ids;
689259bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent    Mutex::Autolock _l(mLock);
6893510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    for (size_t j = 0; j < mTracks.size(); ++j) {
6894510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten        sp<RecordThread::RecordTrack> track = mTracks[j];
6895510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten        int sessionId = track->sessionId();
6896510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten        if (ids.indexOfKey(sessionId) < 0) {
6897510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten            ids.add(sessionId, true);
6898510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten        }
6899510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    }
6900510a3d6b8018a77683dac466127ffd0af34bef6eGlenn Kasten    return ids;
690159bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent}
690259bd0da8373af0e5159b799495fda51e03120ea4Eric Laurent
6903b8ba0a979067a4efb0b3819bf17770793e41c15eEric LaurentAudioFlinger::AudioStreamIn* AudioFlinger::RecordThread::clearInput()
6904b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent{
6905b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    Mutex::Autolock _l(mLock);
6906b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    AudioStreamIn *input = mInput;
6907b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    mInput = NULL;
6908b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    return input;
6909b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent}
6910b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
6911b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent// this method must always be called either with ThreadBase mLock held or inside the thread loop
69120bf65bdde04b8e66c998ff37e2b2afafddddfa33Glenn Kastenaudio_stream_t* AudioFlinger::RecordThread::stream() const
6913b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent{
6914b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    if (mInput == NULL) {
6915b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent        return NULL;
6916b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    }
6917b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    return &mInput->stream->common;
6918b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent}
6919b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
6920b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent
692165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
692265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6923a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurentaudio_module_handle_t AudioFlinger::loadHwModule(const char *name)
6924a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent{
6925a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    if (!settingsAllowed()) {
6926a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        return 0;
6927a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    }
6928a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    Mutex::Autolock _l(mLock);
6929a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    return loadHwModule_l(name);
6930a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent}
6931a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
6932a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent// loadHwModule_l() must be called with AudioFlinger::mLock held
6933a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurentaudio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)
6934a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent{
6935a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
6936a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        if (strncmp(mAudioHwDevs.valueAt(i)->moduleName(), name, strlen(name)) == 0) {
6937a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            ALOGW("loadHwModule() module %s already loaded", name);
6938a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            return mAudioHwDevs.keyAt(i);
6939a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        }
6940a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    }
6941a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
6942a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    audio_hw_device_t *dev;
6943a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
6944f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    int rc = load_audio_interface(name, &dev);
6945a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    if (rc) {
6946a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        ALOGI("loadHwModule() error %d loading module %s ", rc, name);
6947a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        return 0;
6948a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    }
6949a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
6950a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    mHardwareStatus = AUDIO_HW_INIT;
6951a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    rc = dev->init_check(dev);
6952a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    mHardwareStatus = AUDIO_HW_IDLE;
6953a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    if (rc) {
6954a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        ALOGI("loadHwModule() init check error %d for module %s ", rc, name);
6955a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        return 0;
6956a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    }
6957a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
6958ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // Check and cache this HAL's level of support for master mute and master
6959ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // volume.  If this is the first HAL opened, and it supports the get
6960ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // methods, use the initial values provided by the HAL as the current
6961ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    // master mute and volume settings.
6962ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman
6963ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    AudioHwDevice::Flags flags = static_cast<AudioHwDevice::Flags>(0);
6964ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    {  // scope for auto-lock pattern
6965a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        AutoMutex lock(mHardwareLock);
6966ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman
6967ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        if (0 == mAudioHwDevs.size()) {
6968ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman            mHardwareStatus = AUDIO_HW_GET_MASTER_VOLUME;
6969ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman            if (NULL != dev->get_master_volume) {
6970ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman                float mv;
6971ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman                if (OK == dev->get_master_volume(dev, &mv)) {
6972ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman                    mMasterVolume = mv;
6973ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman                }
6974ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman            }
6975ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman
6976ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman            mHardwareStatus = AUDIO_HW_GET_MASTER_MUTE;
6977ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman            if (NULL != dev->get_master_mute) {
6978ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman                bool mm;
6979ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman                if (OK == dev->get_master_mute(dev, &mm)) {
6980ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman                    mMasterMute = mm;
6981ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman                }
6982ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman            }
6983ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        }
6984ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman
6985a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
6986ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        if ((NULL != dev->set_master_volume) &&
6987ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman            (OK == dev->set_master_volume(dev, mMasterVolume))) {
6988ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman            flags = static_cast<AudioHwDevice::Flags>(flags |
6989ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman                    AudioHwDevice::AHWD_CAN_SET_MASTER_VOLUME);
6990ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        }
6991ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman
6992ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE;
6993ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        if ((NULL != dev->set_master_mute) &&
6994ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman            (OK == dev->set_master_mute(dev, mMasterMute))) {
6995ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman            flags = static_cast<AudioHwDevice::Flags>(flags |
6996ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman                    AudioHwDevice::AHWD_CAN_SET_MASTER_MUTE);
6997ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        }
6998ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman
6999a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        mHardwareStatus = AUDIO_HW_IDLE;
7000a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    }
7001a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
7002a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    audio_module_handle_t handle = nextUniqueId();
7003ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    mAudioHwDevs.add(handle, new AudioHwDevice(name, dev, flags));
7004a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
7005a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    ALOGI("loadHwModule() Loaded %s audio interface from %s (%s) handle %d",
7006f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent          name, dev->common.module->name, dev->common.module->id, handle);
7007a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
7008a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    return handle;
7009a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
7010a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent}
7011a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
7012cc0f1cfb69ce8b8985fc2c0984847a06a13ad22dGlenn Kasten// ----------------------------------------------------------------------------
7013cc0f1cfb69ce8b8985fc2c0984847a06a13ad22dGlenn Kasten
70143b16c766d1ae2cfd8487e8ffb2b23936fc0a8e17Glenn Kastenuint32_t AudioFlinger::getPrimaryOutputSamplingRate()
7015cc0f1cfb69ce8b8985fc2c0984847a06a13ad22dGlenn Kasten{
7016cc0f1cfb69ce8b8985fc2c0984847a06a13ad22dGlenn Kasten    Mutex::Autolock _l(mLock);
7017cc0f1cfb69ce8b8985fc2c0984847a06a13ad22dGlenn Kasten    PlaybackThread *thread = primaryPlaybackThread_l();
7018cc0f1cfb69ce8b8985fc2c0984847a06a13ad22dGlenn Kasten    return thread != NULL ? thread->sampleRate() : 0;
7019cc0f1cfb69ce8b8985fc2c0984847a06a13ad22dGlenn Kasten}
7020cc0f1cfb69ce8b8985fc2c0984847a06a13ad22dGlenn Kasten
7021e33054eb968cbf8ccaee1b0ff0301403902deed6Glenn Kastensize_t AudioFlinger::getPrimaryOutputFrameCount()
7022cc0f1cfb69ce8b8985fc2c0984847a06a13ad22dGlenn Kasten{
7023cc0f1cfb69ce8b8985fc2c0984847a06a13ad22dGlenn Kasten    Mutex::Autolock _l(mLock);
7024cc0f1cfb69ce8b8985fc2c0984847a06a13ad22dGlenn Kasten    PlaybackThread *thread = primaryPlaybackThread_l();
7025cc0f1cfb69ce8b8985fc2c0984847a06a13ad22dGlenn Kasten    return thread != NULL ? thread->frameCountHAL() : 0;
7026cc0f1cfb69ce8b8985fc2c0984847a06a13ad22dGlenn Kasten}
7027cc0f1cfb69ce8b8985fc2c0984847a06a13ad22dGlenn Kasten
7028cc0f1cfb69ce8b8985fc2c0984847a06a13ad22dGlenn Kasten// ----------------------------------------------------------------------------
7029cc0f1cfb69ce8b8985fc2c0984847a06a13ad22dGlenn Kasten
7030a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurentaudio_io_handle_t AudioFlinger::openOutput(audio_module_handle_t module,
7031a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                           audio_devices_t *pDevices,
7032a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                           uint32_t *pSamplingRate,
7033a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                           audio_format_t *pFormat,
7034a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                           audio_channel_mask_t *pChannelMask,
7035a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                           uint32_t *pLatencyMs,
70360ca3cf94c0dfc173ad7886ae162c4b67067539f6Eric Laurent                                           audio_output_flags_t flags)
703765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
703865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t status;
703965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *thread = NULL;
7040f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    struct audio_config config = {
7041f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        sample_rate: pSamplingRate ? *pSamplingRate : 0,
7042f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        channel_mask: pChannelMask ? *pChannelMask : 0,
7043f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        format: pFormat ? *pFormat : AUDIO_FORMAT_DEFAULT,
7044f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    };
7045f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    audio_stream_out_t *outStream = NULL;
7046ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    AudioHwDevice *outHwDev;
704765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7048a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    ALOGV("openOutput(), module %d Device %x, SamplingRate %d, Format %d, Channels %x, flags %x",
7049a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent              module,
7050bb4350d3b9e9485ae59e084de270f86aecef8066Glenn Kasten              (pDevices != NULL) ? *pDevices : 0,
7051f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent              config.sample_rate,
7052f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent              config.format,
7053f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent              config.channel_mask,
7054a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent              flags);
705565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
705665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (pDevices == NULL || *pDevices == 0) {
705765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return 0;
705865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
7059799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
706065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
706165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7062a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    outHwDev = findSuitableHwDev_l(module, *pDevices);
7063799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    if (outHwDev == NULL)
7064799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        return 0;
7065799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
7066ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    audio_hw_device_t *hwDevHal = outHwDev->hwDevice();
7067f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    audio_io_handle_t id = nextUniqueId();
7068f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent
70698abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten    mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
7070f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent
7071ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    status = hwDevHal->open_output_stream(hwDevHal,
7072f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent                                          id,
7073f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent                                          *pDevices,
7074f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent                                          (audio_output_flags_t)flags,
7075f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent                                          &config,
7076f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent                                          &outStream);
7077f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent
70788abf44d2f2bcd20a2835570efe89d89c19db426aGlenn Kasten    mHardwareStatus = AUDIO_HW_IDLE;
707985ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten    ALOGV("openOutput() openOutputStream returned output %p, SamplingRate %d, Format %d, "
708085ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten            "Channels %x, status %d",
7081799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin            outStream,
7082f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent            config.sample_rate,
7083f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent            config.format,
7084f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent            config.channel_mask,
708565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            status);
708665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7087f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    if (status == NO_ERROR && outStream != NULL) {
7088799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        AudioStreamOut *output = new AudioStreamOut(outHwDev, outStream);
7089799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
70900ca3cf94c0dfc173ad7886ae162c4b67067539f6Eric Laurent        if ((flags & AUDIO_OUTPUT_FLAG_DIRECT) ||
7091f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent            (config.format != AUDIO_FORMAT_PCM_16_BIT) ||
7092f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent            (config.channel_mask != AUDIO_CHANNEL_OUT_STEREO)) {
709365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            thread = new DirectOutputThread(this, output, id, *pDevices);
70943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("openOutput() created direct output: ID %d thread %p", id, thread);
709565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
709665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            thread = new MixerThread(this, output, id, *pDevices);
70973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("openOutput() created mixer output: ID %d thread %p", id, thread);
709865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
709965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mPlaybackThreads.add(id, thread);
710065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7101f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        if (pSamplingRate != NULL) *pSamplingRate = config.sample_rate;
7102f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        if (pFormat != NULL) *pFormat = config.format;
7103f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        if (pChannelMask != NULL) *pChannelMask = config.channel_mask;
7104a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten        if (pLatencyMs != NULL) *pLatencyMs = thread->latency();
710565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
710665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // notify client processes of the new output creation
710765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        thread->audioConfigChanged_l(AudioSystem::OUTPUT_OPENED);
7108a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
7109a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        // the first primary output opened designates the primary hw device
71100ca3cf94c0dfc173ad7886ae162c4b67067539f6Eric Laurent        if ((mPrimaryHardwareDev == NULL) && (flags & AUDIO_OUTPUT_FLAG_PRIMARY)) {
7111a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            ALOGI("Using module %d has the primary audio interface", module);
7112a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            mPrimaryHardwareDev = outHwDev;
7113a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
7114a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            AutoMutex lock(mHardwareLock);
7115a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            mHardwareStatus = AUDIO_HW_SET_MODE;
7116ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman            hwDevHal->set_mode(hwDevHal, mMode);
7117a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent            mHardwareStatus = AUDIO_HW_IDLE;
7118a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        }
711965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return id;
712065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
712165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
712265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return 0;
712365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
712465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
712572ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenaudio_io_handle_t AudioFlinger::openDuplicateOutput(audio_io_handle_t output1,
712672ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten        audio_io_handle_t output2)
712765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
712865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
712965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    MixerThread *thread1 = checkMixerThread_l(output1);
713065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    MixerThread *thread2 = checkMixerThread_l(output2);
713165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
713265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread1 == NULL || thread2 == NULL) {
713385ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten        ALOGW("openDuplicateOutput() wrong output mixer type for output %d or %d", output1,
713485ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                output2);
713565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return 0;
713665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
713765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
713872ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten    audio_io_handle_t id = nextUniqueId();
713965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    DuplicatingThread *thread = new DuplicatingThread(this, thread1, id);
714065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    thread->addOutputTrack(thread2);
714165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mPlaybackThreads.add(id, thread);
714265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // notify client processes of the new output creation
714365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    thread->audioConfigChanged_l(AudioSystem::OUTPUT_OPENED);
714465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return id;
714565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
714665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
714772ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenstatus_t AudioFlinger::closeOutput(audio_io_handle_t output)
714865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
7149d96c5724818fb47917bb5e7abe37799735e1ec0eGlenn Kasten    return closeOutput_nonvirtual(output);
7150d96c5724818fb47917bb5e7abe37799735e1ec0eGlenn Kasten}
7151d96c5724818fb47917bb5e7abe37799735e1ec0eGlenn Kasten
7152d96c5724818fb47917bb5e7abe37799735e1ec0eGlenn Kastenstatus_t AudioFlinger::closeOutput_nonvirtual(audio_io_handle_t output)
7153d96c5724818fb47917bb5e7abe37799735e1ec0eGlenn Kasten{
715465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // keep strong reference on the playback thread so that
715565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // it is not destroyed while exit() is executed
7156e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    sp<PlaybackThread> thread;
715765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    {
715865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock _l(mLock);
715965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        thread = checkPlaybackThread_l(output);
716065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (thread == NULL) {
716165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return BAD_VALUE;
716265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
716365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
71643856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("closeOutput() %d", output);
716565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
71667c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        if (thread->type() == ThreadBase::MIXER) {
716765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
71687c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                if (mPlaybackThreads.valueAt(i)->type() == ThreadBase::DUPLICATING) {
716985ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                    DuplicatingThread *dupThread =
717085ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                            (DuplicatingThread *)mPlaybackThreads.valueAt(i).get();
717165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    dupThread->removeOutputTrack((MixerThread *)thread.get());
717265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
717365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
717465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
7175a111792f1314479c649d1d44c30c2caf70c00c2aGlenn Kasten        audioConfigChanged_l(AudioSystem::OUTPUT_CLOSED, output, NULL);
717665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mPlaybackThreads.removeItem(output);
717765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
717865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    thread->exit();
7179b28686f95daee16edeb5f39af2cd5274ac3dc99fGlenn Kasten    // The thread entity (active unit of execution) is no longer running here,
7180b28686f95daee16edeb5f39af2cd5274ac3dc99fGlenn Kasten    // but the ThreadBase container still exists.
718165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
71827c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (thread->type() != ThreadBase::DUPLICATING) {
7183b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent        AudioStreamOut *out = thread->clearOutput();
71845798d4ebf236357a4b13246f40e52b90a34d09a4Glenn Kasten        ALOG_ASSERT(out != NULL, "out shouldn't be NULL");
7185b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent        // from now on thread->mOutput is NULL
7186ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        out->hwDev()->close_output_stream(out->hwDev(), out->stream);
7187799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        delete out;
718865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
718965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
719065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
719165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
719272ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenstatus_t AudioFlinger::suspendOutput(audio_io_handle_t output)
719365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
719465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
719565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *thread = checkPlaybackThread_l(output);
719665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
719765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread == NULL) {
719865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return BAD_VALUE;
719965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
720065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
72013856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("suspendOutput() %d", output);
720265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    thread->suspend();
720365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
720465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
720565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
720665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
720772ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenstatus_t AudioFlinger::restoreOutput(audio_io_handle_t output)
720865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
720965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
721065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *thread = checkPlaybackThread_l(output);
721165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
721265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread == NULL) {
721365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return BAD_VALUE;
721465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
721565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
72163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("restoreOutput() %d", output);
721765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
721865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    thread->restore();
721965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
722065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
722165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
722265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7223a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurentaudio_io_handle_t AudioFlinger::openInput(audio_module_handle_t module,
7224a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                          audio_devices_t *pDevices,
7225a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                          uint32_t *pSamplingRate,
7226a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                          audio_format_t *pFormat,
7227254af180475346b6186b49c297f340c9c4817511Glenn Kasten                                          audio_channel_mask_t *pChannelMask)
722865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
722965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t status;
723065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    RecordThread *thread = NULL;
7231f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    struct audio_config config = {
7232f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        sample_rate: pSamplingRate ? *pSamplingRate : 0,
7233f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        channel_mask: pChannelMask ? *pChannelMask : 0,
7234f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        format: pFormat ? *pFormat : AUDIO_FORMAT_DEFAULT,
7235f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    };
7236f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    uint32_t reqSamplingRate = config.sample_rate;
7237f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    audio_format_t reqFormat = config.format;
7238f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    audio_channel_mask_t reqChannels = config.channel_mask;
7239f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    audio_stream_in_t *inStream = NULL;
7240ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    AudioHwDevice *inHwDev;
724165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
724265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (pDevices == NULL || *pDevices == 0) {
724365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return 0;
724465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
7245799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
724665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
724765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7248a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    inHwDev = findSuitableHwDev_l(module, *pDevices);
7249799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    if (inHwDev == NULL)
7250799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        return 0;
7251799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
7252ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    audio_hw_device_t *inHwHal = inHwDev->hwDevice();
7253f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    audio_io_handle_t id = nextUniqueId();
7254f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent
7255ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    status = inHwHal->open_input_stream(inHwHal, id, *pDevices, &config,
7256799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin                                        &inStream);
725785ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten    ALOGV("openInput() openInputStream returned input %p, SamplingRate %d, Format %d, Channels %x, "
725885ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten            "status %d",
7259799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin            inStream,
7260f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent            config.sample_rate,
7261f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent            config.format,
7262f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent            config.channel_mask,
726365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            status);
726465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
726585ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten    // If the input could not be opened with the requested parameters and we can handle the
726685ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten    // conversion internally, try to open again with the proposed parameters. The AudioFlinger can
726785ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten    // resample the input and do mono to stereo or stereo to mono conversions on 16 bit PCM inputs.
7268f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    if (status == BAD_VALUE &&
7269f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        reqFormat == config.format && config.format == AUDIO_FORMAT_PCM_16_BIT &&
7270f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        (config.sample_rate <= 2 * reqSamplingRate) &&
7271f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        (popcount(config.channel_mask) <= FCC_2) && (popcount(reqChannels) <= FCC_2)) {
7272254af180475346b6186b49c297f340c9c4817511Glenn Kasten        ALOGV("openInput() reopening with proposed sampling rate and channel mask");
7273f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        inStream = NULL;
7274ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        status = inHwHal->open_input_stream(inHwHal, id, *pDevices, &config, &inStream);
727565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
727665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7277f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent    if (status == NO_ERROR && inStream != NULL) {
7278d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten
7279d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        // Try to re-use most recently used Pipe to archive a copy of input for dumpsys,
7280d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        // or (re-)create if current Pipe is idle and does not match the new format
7281d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        sp<NBAIO_Sink> teeSink;
7282d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten#ifdef TEE_SINK_INPUT_FRAMES
7283d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        enum {
7284d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            TEE_SINK_NO,    // don't copy input
7285d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            TEE_SINK_NEW,   // copy input using a new pipe
7286d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            TEE_SINK_OLD,   // copy input using an existing pipe
7287d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        } kind;
7288d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        NBAIO_Format format = Format_from_SR_C(inStream->common.get_sample_rate(&inStream->common),
7289d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten                                        popcount(inStream->common.get_channels(&inStream->common)));
7290d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        if (format == Format_Invalid) {
7291d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            kind = TEE_SINK_NO;
7292d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        } else if (mRecordTeeSink == 0) {
7293d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            kind = TEE_SINK_NEW;
7294d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        } else if (mRecordTeeSink->getStrongCount() != 1) {
7295d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            kind = TEE_SINK_NO;
7296d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        } else if (format == mRecordTeeSink->format()) {
7297d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            kind = TEE_SINK_OLD;
7298d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        } else {
7299d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            kind = TEE_SINK_NEW;
7300d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        }
7301d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        switch (kind) {
7302d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        case TEE_SINK_NEW: {
7303d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            Pipe *pipe = new Pipe(TEE_SINK_INPUT_FRAMES, format);
7304d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            size_t numCounterOffers = 0;
7305d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            const NBAIO_Format offers[1] = {format};
7306d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            ssize_t index = pipe->negotiate(offers, 1, NULL, numCounterOffers);
7307d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            ALOG_ASSERT(index == 0);
7308d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            PipeReader *pipeReader = new PipeReader(*pipe);
7309d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            numCounterOffers = 0;
7310d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            index = pipeReader->negotiate(offers, 1, NULL, numCounterOffers);
7311d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            ALOG_ASSERT(index == 0);
7312d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            mRecordTeeSink = pipe;
7313d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            mRecordTeeSource = pipeReader;
7314d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            teeSink = pipe;
7315d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            }
7316d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            break;
7317d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        case TEE_SINK_OLD:
7318d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            teeSink = mRecordTeeSink;
7319d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            break;
7320d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        case TEE_SINK_NO:
7321d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        default:
7322d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten            break;
7323d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten        }
7324d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten#endif
7325799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin        AudioStreamIn *input = new AudioStreamIn(inHwDev, inStream);
7326799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin
73277c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        // Start record thread
73287c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        // RecorThread require both input and output device indication to forward to audio
73297c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        // pre processing modules
7330bb4350d3b9e9485ae59e084de270f86aecef8066Glenn Kasten        audio_devices_t device = (*pDevices) | primaryOutputDevice_l();
7331d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten
73327c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        thread = new RecordThread(this,
73337c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                  input,
73347c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                  reqSamplingRate,
73357c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                  reqChannels,
73367c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                  id,
7337d06785bebf7e43d4a011b62a252771373ada910cGlenn Kasten                                  device, teeSink);
733865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mRecordThreads.add(id, thread);
73393856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("openInput() created record thread: ID %d thread %p", id, thread);
7340a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten        if (pSamplingRate != NULL) *pSamplingRate = reqSamplingRate;
7341f7ffb8bf0a58037f0bc9662c5275005a4e539948Eric Laurent        if (pFormat != NULL) *pFormat = config.format;
7342a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        if (pChannelMask != NULL) *pChannelMask = reqChannels;
734365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
734465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // notify client processes of the new input creation
734565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        thread->audioConfigChanged_l(AudioSystem::INPUT_OPENED);
734665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return id;
734765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
734865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
734965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return 0;
735065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
735165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
735272ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenstatus_t AudioFlinger::closeInput(audio_io_handle_t input)
735365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
7354d96c5724818fb47917bb5e7abe37799735e1ec0eGlenn Kasten    return closeInput_nonvirtual(input);
7355d96c5724818fb47917bb5e7abe37799735e1ec0eGlenn Kasten}
7356d96c5724818fb47917bb5e7abe37799735e1ec0eGlenn Kasten
7357d96c5724818fb47917bb5e7abe37799735e1ec0eGlenn Kastenstatus_t AudioFlinger::closeInput_nonvirtual(audio_io_handle_t input)
7358d96c5724818fb47917bb5e7abe37799735e1ec0eGlenn Kasten{
735965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // keep strong reference on the record thread so that
736065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // it is not destroyed while exit() is executed
7361e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    sp<RecordThread> thread;
736265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    {
736365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock _l(mLock);
736465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        thread = checkRecordThread_l(input);
7365d5903ec1332630f2992a6f0d5ca69d13a185c665Glenn Kasten        if (thread == 0) {
736665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return BAD_VALUE;
736765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
736865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
73693856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("closeInput() %d", input);
7370a111792f1314479c649d1d44c30c2caf70c00c2aGlenn Kasten        audioConfigChanged_l(AudioSystem::INPUT_CLOSED, input, NULL);
737165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mRecordThreads.removeItem(input);
737265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
737365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    thread->exit();
7374b28686f95daee16edeb5f39af2cd5274ac3dc99fGlenn Kasten    // The thread entity (active unit of execution) is no longer running here,
7375b28686f95daee16edeb5f39af2cd5274ac3dc99fGlenn Kasten    // but the ThreadBase container still exists.
737665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7377b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    AudioStreamIn *in = thread->clearInput();
73785798d4ebf236357a4b13246f40e52b90a34d09a4Glenn Kasten    ALOG_ASSERT(in != NULL, "in shouldn't be NULL");
7379b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent    // from now on thread->mInput is NULL
7380ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman    in->hwDev()->close_input_stream(in->hwDev(), in->stream);
7381799a70e7028a4d714436c3a744a775acfbd31aaeDima Zavin    delete in;
738265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
738365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
738465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
738565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
738672ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenstatus_t AudioFlinger::setStreamOutput(audio_stream_type_t stream, audio_io_handle_t output)
738765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
738865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
73893856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setStreamOutput() stream %d to output %d", stream, output);
739065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
739165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
739265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
739322167855ff9af7b13fda669ca27c67a037a7d585Eric Laurent        thread->invalidateTracks(stream);
7394de070137f11d346fba77605bd76a44c040a618fcEric Laurent    }
739565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
739665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
739765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
739865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
739965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
740065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianint AudioFlinger::newAudioSessionId()
740165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
74027c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    return nextUniqueId();
740365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
740465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
74053a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissenvoid AudioFlinger::acquireAudioSessionId(int audioSession)
74063a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen{
74073a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    Mutex::Autolock _l(mLock);
7408bb001926447d0b7dc71ca8bb3c9856f3136d8f4cGlenn Kasten    pid_t caller = IPCThreadState::self()->getCallingPid();
74093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("acquiring %d from %d", audioSession, caller);
74108d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    size_t num = mAudioSessionRefs.size();
74118d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    for (size_t i = 0; i< num; i++) {
74123a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        AudioSessionRef *ref = mAudioSessionRefs.editItemAt(i);
7413012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten        if (ref->mSessionid == audioSession && ref->mPid == caller) {
7414012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten            ref->mCnt++;
7415012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten            ALOGV(" incremented refcount to %d", ref->mCnt);
74163a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            return;
74173a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        }
74183a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    }
741984afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten    mAudioSessionRefs.push(new AudioSessionRef(audioSession, caller));
742084afa3b51ac48f84ed62489529ce78cba7fca00eGlenn Kasten    ALOGV(" added new entry for %d", audioSession);
74213a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen}
74223a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen
74233a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissenvoid AudioFlinger::releaseAudioSessionId(int audioSession)
74243a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen{
74253a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    Mutex::Autolock _l(mLock);
7426bb001926447d0b7dc71ca8bb3c9856f3136d8f4cGlenn Kasten    pid_t caller = IPCThreadState::self()->getCallingPid();
74273856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("releasing %d from %d", audioSession, caller);
74288d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    size_t num = mAudioSessionRefs.size();
74298d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    for (size_t i = 0; i< num; i++) {
74303a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        AudioSessionRef *ref = mAudioSessionRefs.itemAt(i);
7431012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten        if (ref->mSessionid == audioSession && ref->mPid == caller) {
7432012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten            ref->mCnt--;
7433012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten            ALOGV(" decremented refcount to %d", ref->mCnt);
7434012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten            if (ref->mCnt == 0) {
74353a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen                mAudioSessionRefs.removeAt(i);
74363a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen                delete ref;
74373a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen                purgeStaleEffects_l();
74383a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            }
74393a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            return;
74403a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        }
74413a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    }
74425ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block    ALOGW("session id %d not found for pid %d", audioSession, caller);
74433a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen}
74443a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen
74453a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissenvoid AudioFlinger::purgeStaleEffects_l() {
74463a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen
74473856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("purging stale effects");
74483a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen
74493a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    Vector< sp<EffectChain> > chains;
74503a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen
74513a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
74523a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        sp<PlaybackThread> t = mPlaybackThreads.valueAt(i);
74533a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        for (size_t j = 0; j < t->mEffectChains.size(); j++) {
74543a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            sp<EffectChain> ec = t->mEffectChains[j];
74550270b188aa3929cc512ec6869caba1d6b60cc08cMarco Nelissen            if (ec->sessionId() > AUDIO_SESSION_OUTPUT_MIX) {
74560270b188aa3929cc512ec6869caba1d6b60cc08cMarco Nelissen                chains.push(ec);
74570270b188aa3929cc512ec6869caba1d6b60cc08cMarco Nelissen            }
74583a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        }
74593a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    }
74603a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    for (size_t i = 0; i < mRecordThreads.size(); i++) {
74613a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        sp<RecordThread> t = mRecordThreads.valueAt(i);
74623a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        for (size_t j = 0; j < t->mEffectChains.size(); j++) {
74633a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            sp<EffectChain> ec = t->mEffectChains[j];
74643a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            chains.push(ec);
74653a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        }
74663a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    }
74673a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen
74683a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    for (size_t i = 0; i < chains.size(); i++) {
74693a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        sp<EffectChain> ec = chains[i];
74703a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        int sessionid = ec->sessionId();
74713a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        sp<ThreadBase> t = ec->mThread.promote();
74723a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        if (t == 0) {
74733a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            continue;
74743a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        }
74753a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        size_t numsessionrefs = mAudioSessionRefs.size();
74763a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        bool found = false;
74773a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        for (size_t k = 0; k < numsessionrefs; k++) {
74783a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            AudioSessionRef *ref = mAudioSessionRefs.itemAt(k);
7479012ca6b4f69fb24385025c0e84b8f816525a3032Glenn Kasten            if (ref->mSessionid == sessionid) {
74803856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV(" session %d still exists for %d with %d refs",
7481e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    sessionid, ref->mPid, ref->mCnt);
74823a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen                found = true;
74833a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen                break;
74843a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            }
74853a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        }
74863a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        if (!found) {
7487a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent            Mutex::Autolock _l (t->mLock);
74883a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            // remove all effects from the chain
74893a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            while (ec->mEffects.size()) {
74903a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen                sp<EffectModule> effect = ec->mEffects[0];
74913a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen                effect->unPin();
74923a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen                t->removeEffect_l(effect);
7493a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent                if (effect->purgeHandles()) {
7494a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent                    t->checkSuspendOnEffectEnabled_l(effect, false, effect->sessionId());
74953a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen                }
74963a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen                AudioSystem::unregisterEffect(effect->id());
74973a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            }
74983a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        }
74993a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    }
75003a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    return;
75013a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen}
75023a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen
750365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// checkPlaybackThread_l() must be called with AudioFlinger::mLock held
750472ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn KastenAudioFlinger::PlaybackThread *AudioFlinger::checkPlaybackThread_l(audio_io_handle_t output) const
750565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
7506a111792f1314479c649d1d44c30c2caf70c00c2aGlenn Kasten    return mPlaybackThreads.valueFor(output).get();
750765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
750865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
750965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// checkMixerThread_l() must be called with AudioFlinger::mLock held
751072ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn KastenAudioFlinger::MixerThread *AudioFlinger::checkMixerThread_l(audio_io_handle_t output) const
751165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
751265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    PlaybackThread *thread = checkPlaybackThread_l(output);
7513a111792f1314479c649d1d44c30c2caf70c00c2aGlenn Kasten    return thread != NULL && thread->type() != ThreadBase::DIRECT ? (MixerThread *) thread : NULL;
751465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
751565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
751665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// checkRecordThread_l() must be called with AudioFlinger::mLock held
751772ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn KastenAudioFlinger::RecordThread *AudioFlinger::checkRecordThread_l(audio_io_handle_t input) const
751865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
7519a111792f1314479c649d1d44c30c2caf70c00c2aGlenn Kasten    return mRecordThreads.valueFor(input).get();
752065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
752165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
75227c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurentuint32_t AudioFlinger::nextUniqueId()
75237c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent{
75247c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    return android_atomic_inc(&mNextUniqueId);
75257c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent}
75267c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
752702fe1bf923bbe5789202dbd5810e2c04794562e6Glenn KastenAudioFlinger::PlaybackThread *AudioFlinger::primaryPlaybackThread_l() const
752865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
75297c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
75307c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
7531b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent        AudioStreamOut *output = thread->getOutput();
7532ee578c0330319f04a48bccbdb26b53fea0388d04John Grossman        if (output != NULL && output->audioHwDev == mPrimaryHardwareDev) {
75337c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            return thread;
75347c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        }
75357c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
75367c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    return NULL;
75377c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent}
75387c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
7539bb4350d3b9e9485ae59e084de270f86aecef8066Glenn Kastenaudio_devices_t AudioFlinger::primaryOutputDevice_l() const
75407c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent{
75417c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    PlaybackThread *thread = primaryPlaybackThread_l();
75427c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
75437c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (thread == NULL) {
75447c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        return 0;
75457c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
75467c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
7547f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent    return thread->outDevice();
754865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
754965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7550a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurentsp<AudioFlinger::SyncEvent> AudioFlinger::createSyncEvent(AudioSystem::sync_event_t type,
7551a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                                    int triggerSession,
7552a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                                    int listenerSession,
7553a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                                    sync_event_callback_t callBack,
7554a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                                    void *cookie)
7555a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent{
7556a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    Mutex::Autolock _l(mLock);
7557a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent
7558a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    sp<SyncEvent> event = new SyncEvent(type, triggerSession, listenerSession, callBack, cookie);
7559a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    status_t playStatus = NAME_NOT_FOUND;
7560a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    status_t recStatus = NAME_NOT_FOUND;
7561a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
7562a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        playStatus = mPlaybackThreads.valueAt(i)->setSyncEvent(event);
7563a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        if (playStatus == NO_ERROR) {
7564a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent            return event;
7565a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        }
7566a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    }
7567a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    for (size_t i = 0; i < mRecordThreads.size(); i++) {
7568a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        recStatus = mRecordThreads.valueAt(i)->setSyncEvent(event);
7569a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        if (recStatus == NO_ERROR) {
7570a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent            return event;
7571a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        }
7572a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    }
7573a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    if (playStatus == NAME_NOT_FOUND || recStatus == NAME_NOT_FOUND) {
7574a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        mPendingSyncEvents.add(event);
7575a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    } else {
7576a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        ALOGV("createSyncEvent() invalid event %d", event->type());
7577a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent        event.clear();
7578a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    }
7579a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    return event;
7580a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent}
75817c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
758265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
758365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian//  Effect management
758465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
758565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
758665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7587f587ba5b991c7cd91e4df093d0d796bd419e5d67Glenn Kastenstatus_t AudioFlinger::queryNumberEffects(uint32_t *numEffects) const
758865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
758965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
759065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return EffectQueryNumberEffects(numEffects);
759165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
759265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7593f587ba5b991c7cd91e4df093d0d796bd419e5d67Glenn Kastenstatus_t AudioFlinger::queryEffect(uint32_t index, effect_descriptor_t *descriptor) const
759465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
759565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
759665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return EffectQueryEffect(index, descriptor);
759765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
759865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
75995e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenstatus_t AudioFlinger::getEffectDescriptor(const effect_uuid_t *pUuid,
7600f587ba5b991c7cd91e4df093d0d796bd419e5d67Glenn Kasten        effect_descriptor_t *descriptor) const
760165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
760265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
760365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return EffectGetDescriptor(pUuid, descriptor);
760465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
760565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
760665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
760765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansp<IEffect> AudioFlinger::createEffect(pid_t pid,
760865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        effect_descriptor_t *pDesc,
760965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        const sp<IEffectClient>& effectClient,
761065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int32_t priority,
761172ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten        audio_io_handle_t io,
761265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int sessionId,
761365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status_t *status,
761465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int *id,
761565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int *enabled)
761665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
761765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t lStatus = NO_ERROR;
761865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<EffectHandle> handle;
761965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    effect_descriptor_t desc;
762065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
762198ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten    ALOGV("createEffect pid %d, effectClient %p, priority %d, sessionId %d, io %d",
76227c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            pid, effectClient.get(), priority, sessionId, io);
762365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
762465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (pDesc == NULL) {
762565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        lStatus = BAD_VALUE;
762665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        goto Exit;
762765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
762865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
762984e9a10fde8a4ae3da4f88d7911c154933aa457fEric Laurent    // check audio settings permission for global effects
7630fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (sessionId == AUDIO_SESSION_OUTPUT_MIX && !settingsAllowed()) {
763184e9a10fde8a4ae3da4f88d7911c154933aa457fEric Laurent        lStatus = PERMISSION_DENIED;
763284e9a10fde8a4ae3da4f88d7911c154933aa457fEric Laurent        goto Exit;
763384e9a10fde8a4ae3da4f88d7911c154933aa457fEric Laurent    }
763465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7635fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    // Session AUDIO_SESSION_OUTPUT_STAGE is reserved for output stage effects
763684e9a10fde8a4ae3da4f88d7911c154933aa457fEric Laurent    // that can only be created by audio policy manager (running in same process)
763744deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten    if (sessionId == AUDIO_SESSION_OUTPUT_STAGE && getpid_cached != pid) {
763884e9a10fde8a4ae3da4f88d7911c154933aa457fEric Laurent        lStatus = PERMISSION_DENIED;
763984e9a10fde8a4ae3da4f88d7911c154933aa457fEric Laurent        goto Exit;
764084e9a10fde8a4ae3da4f88d7911c154933aa457fEric Laurent    }
7641fac4895de4ae63928ff0cf2ccece106eb6d33f72Eric Laurent
76427c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (io == 0) {
7643fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        if (sessionId == AUDIO_SESSION_OUTPUT_STAGE) {
764484e9a10fde8a4ae3da4f88d7911c154933aa457fEric Laurent            // output must be specified by AudioPolicyManager when using session
7645fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin            // AUDIO_SESSION_OUTPUT_STAGE
764684e9a10fde8a4ae3da4f88d7911c154933aa457fEric Laurent            lStatus = BAD_VALUE;
7647fac4895de4ae63928ff0cf2ccece106eb6d33f72Eric Laurent            goto Exit;
7648fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        } else if (sessionId == AUDIO_SESSION_OUTPUT_MIX) {
764984e9a10fde8a4ae3da4f88d7911c154933aa457fEric Laurent            // if the output returned by getOutputForEffect() is removed before we lock the
76507c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            // mutex below, the call to checkPlaybackThread_l(io) below will detect it
765184e9a10fde8a4ae3da4f88d7911c154933aa457fEric Laurent            // and we will exit safely
76527c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            io = AudioSystem::getOutputForEffect(&desc);
765365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
765484e9a10fde8a4ae3da4f88d7911c154933aa457fEric Laurent    }
765584e9a10fde8a4ae3da4f88d7911c154933aa457fEric Laurent
765684e9a10fde8a4ae3da4f88d7911c154933aa457fEric Laurent    {
765784e9a10fde8a4ae3da4f88d7911c154933aa457fEric Laurent        Mutex::Autolock _l(mLock);
765884e9a10fde8a4ae3da4f88d7911c154933aa457fEric Laurent
765965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
766065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!EffectIsNullUuid(&pDesc->uuid)) {
766165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // if uuid is specified, request effect descriptor
766265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            lStatus = EffectGetDescriptor(&pDesc->uuid, &desc);
766365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (lStatus < 0) {
76645ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block                ALOGW("createEffect() error %d from EffectGetDescriptor", lStatus);
766565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                goto Exit;
766665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
766765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
766865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // if uuid is not specified, look for an available implementation
766965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // of the required type in effect factory
767065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (EffectIsNullUuid(&pDesc->type)) {
76715ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block                ALOGW("createEffect() no effect type");
767265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                lStatus = BAD_VALUE;
767365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                goto Exit;
767465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
767565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            uint32_t numEffects = 0;
767665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            effect_descriptor_t d;
76773a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            d.flags = 0; // prevent compiler warning
767865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            bool found = false;
767965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
768065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            lStatus = EffectQueryNumberEffects(&numEffects);
768165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (lStatus < 0) {
76825ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block                ALOGW("createEffect() error %d from EffectQueryNumberEffects", lStatus);
768365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                goto Exit;
768465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
768565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            for (uint32_t i = 0; i < numEffects; i++) {
768665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                lStatus = EffectQueryEffect(i, &desc);
768765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (lStatus < 0) {
76885ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block                    ALOGW("createEffect() error %d from EffectQueryEffect", lStatus);
768965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    continue;
769065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
769165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (memcmp(&desc.type, &pDesc->type, sizeof(effect_uuid_t)) == 0) {
769265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    // If matching type found save effect descriptor. If the session is
769365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    // 0 and the effect is not auxiliary, continue enumeration in case
769465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    // an auxiliary version of this effect type is available
769565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    found = true;
7696a189a6883ee55cf62da1d7bf5bf5a8ab501938a4Glenn Kasten                    d = desc;
7697fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                    if (sessionId != AUDIO_SESSION_OUTPUT_MIX ||
769865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            (desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
769965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        break;
770065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    }
770165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
770265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
770365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (!found) {
770465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                lStatus = BAD_VALUE;
77055ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block                ALOGW("createEffect() effect not found");
770665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                goto Exit;
770765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
770865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // For same effect type, chose auxiliary version over insert version if
770965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // connect to output mix (Compliance to OpenSL ES)
7710fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin            if (sessionId == AUDIO_SESSION_OUTPUT_MIX &&
771165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    (d.flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_AUXILIARY) {
7712a189a6883ee55cf62da1d7bf5bf5a8ab501938a4Glenn Kasten                desc = d;
771365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
771465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
771565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
771665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Do not allow auxiliary effects on a session different from 0 (output mix)
7717fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        if (sessionId != AUDIO_SESSION_OUTPUT_MIX &&
771865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian             (desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
771965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            lStatus = INVALID_OPERATION;
772065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            goto Exit;
772165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
772265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
772359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        // check recording permission for visualizer
772459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        if ((memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) &&
772559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            !recordingAllowed()) {
772659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            lStatus = PERMISSION_DENIED;
772759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            goto Exit;
772859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
772959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
773065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // return effect descriptor
7731a189a6883ee55cf62da1d7bf5bf5a8ab501938a4Glenn Kasten        *pDesc = desc;
773265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
773365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // If output is not specified try to find a matching audio session ID in one of the
773465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // output threads.
773584e9a10fde8a4ae3da4f88d7911c154933aa457fEric Laurent        // If output is 0 here, sessionId is neither SESSION_OUTPUT_STAGE nor SESSION_OUTPUT_MIX
773684e9a10fde8a4ae3da4f88d7911c154933aa457fEric Laurent        // because of code checking output when entering the function.
77377c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        // Note: io is never 0 when creating an effect on an input
77387c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        if (io == 0) {
7739e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten            // look for the thread where the specified audio session is present
774084e9a10fde8a4ae3da4f88d7911c154933aa457fEric Laurent            for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
774184e9a10fde8a4ae3da4f88d7911c154933aa457fEric Laurent                if (mPlaybackThreads.valueAt(i)->hasAudioSession(sessionId) != 0) {
77427c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                    io = mPlaybackThreads.keyAt(i);
774384e9a10fde8a4ae3da4f88d7911c154933aa457fEric Laurent                    break;
774439e94f8f723d445447fdee0822291e664b631f60Eric Laurent                }
774565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
77467c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            if (io == 0) {
7747e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                for (size_t i = 0; i < mRecordThreads.size(); i++) {
7748e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    if (mRecordThreads.valueAt(i)->hasAudioSession(sessionId) != 0) {
7749e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                        io = mRecordThreads.keyAt(i);
7750e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                        break;
7751e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    }
7752e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                }
77537c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            }
775484e9a10fde8a4ae3da4f88d7911c154933aa457fEric Laurent            // If no output thread contains the requested session ID, default to
775584e9a10fde8a4ae3da4f88d7911c154933aa457fEric Laurent            // first output. The effect chain will be moved to the correct output
775684e9a10fde8a4ae3da4f88d7911c154933aa457fEric Laurent            // thread when a track with the same session ID is created
77577c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            if (io == 0 && mPlaybackThreads.size()) {
77587c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                io = mPlaybackThreads.keyAt(0);
775984e9a10fde8a4ae3da4f88d7911c154933aa457fEric Laurent            }
77603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("createEffect() got io %d for effect %s", io, desc.name);
776165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
77627c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        ThreadBase *thread = checkRecordThread_l(io);
776365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (thread == NULL) {
77647c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            thread = checkPlaybackThread_l(io);
77657c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            if (thread == NULL) {
776629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                ALOGE("createEffect() unknown output thread");
77677c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                lStatus = BAD_VALUE;
77687c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                goto Exit;
77697c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            }
777065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
777165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
777298ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten        sp<Client> client = registerPid_l(pid);
777365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
77743a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        // create effect on selected output thread
7775de070137f11d346fba77605bd76a44c040a618fcEric Laurent        handle = thread->createEffect_l(client, effectClient, priority, sessionId,
7776de070137f11d346fba77605bd76a44c040a618fcEric Laurent                &desc, enabled, &lStatus);
777765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (handle != 0 && id != NULL) {
777865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            *id = handle->id();
777965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
778065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
778165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
778265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianExit:
7783e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    if (status != NULL) {
778465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        *status = lStatus;
778565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
778665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return handle;
778765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
778865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
778972ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenstatus_t AudioFlinger::moveEffects(int sessionId, audio_io_handle_t srcOutput,
779072ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten        audio_io_handle_t dstOutput)
7791de070137f11d346fba77605bd76a44c040a618fcEric Laurent{
77923856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("moveEffects() session %d, srcOutput %d, dstOutput %d",
779359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            sessionId, srcOutput, dstOutput);
7794de070137f11d346fba77605bd76a44c040a618fcEric Laurent    Mutex::Autolock _l(mLock);
7795de070137f11d346fba77605bd76a44c040a618fcEric Laurent    if (srcOutput == dstOutput) {
77965ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("moveEffects() same dst and src outputs %d", dstOutput);
7797de070137f11d346fba77605bd76a44c040a618fcEric Laurent        return NO_ERROR;
779865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
7799de070137f11d346fba77605bd76a44c040a618fcEric Laurent    PlaybackThread *srcThread = checkPlaybackThread_l(srcOutput);
7800de070137f11d346fba77605bd76a44c040a618fcEric Laurent    if (srcThread == NULL) {
78015ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("moveEffects() bad srcOutput %d", srcOutput);
7802de070137f11d346fba77605bd76a44c040a618fcEric Laurent        return BAD_VALUE;
7803de070137f11d346fba77605bd76a44c040a618fcEric Laurent    }
7804de070137f11d346fba77605bd76a44c040a618fcEric Laurent    PlaybackThread *dstThread = checkPlaybackThread_l(dstOutput);
7805de070137f11d346fba77605bd76a44c040a618fcEric Laurent    if (dstThread == NULL) {
78065ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("moveEffects() bad dstOutput %d", dstOutput);
7807de070137f11d346fba77605bd76a44c040a618fcEric Laurent        return BAD_VALUE;
780865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
7809de070137f11d346fba77605bd76a44c040a618fcEric Laurent
7810de070137f11d346fba77605bd76a44c040a618fcEric Laurent    Mutex::Autolock _dl(dstThread->mLock);
7811de070137f11d346fba77605bd76a44c040a618fcEric Laurent    Mutex::Autolock _sl(srcThread->mLock);
781259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    moveEffectChain_l(sessionId, srcThread, dstThread, false);
7813de070137f11d346fba77605bd76a44c040a618fcEric Laurent
781465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
781565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
781665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
78173a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen// moveEffectChain_l must be called with both srcThread and dstThread mLocks held
781859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurentstatus_t AudioFlinger::moveEffectChain_l(int sessionId,
7819de070137f11d346fba77605bd76a44c040a618fcEric Laurent                                   AudioFlinger::PlaybackThread *srcThread,
782039e94f8f723d445447fdee0822291e664b631f60Eric Laurent                                   AudioFlinger::PlaybackThread *dstThread,
782139e94f8f723d445447fdee0822291e664b631f60Eric Laurent                                   bool reRegister)
7822de070137f11d346fba77605bd76a44c040a618fcEric Laurent{
78233856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("moveEffectChain_l() session %d from thread %p to thread %p",
782459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            sessionId, srcThread, dstThread);
7825de070137f11d346fba77605bd76a44c040a618fcEric Laurent
782659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    sp<EffectChain> chain = srcThread->getEffectChain_l(sessionId);
7827de070137f11d346fba77605bd76a44c040a618fcEric Laurent    if (chain == 0) {
78285ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("moveEffectChain_l() effect chain for session %d not on source thread %p",
782959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                sessionId, srcThread);
7830de070137f11d346fba77605bd76a44c040a618fcEric Laurent        return INVALID_OPERATION;
7831de070137f11d346fba77605bd76a44c040a618fcEric Laurent    }
7832de070137f11d346fba77605bd76a44c040a618fcEric Laurent
783339e94f8f723d445447fdee0822291e664b631f60Eric Laurent    // remove chain first. This is useful only if reconfiguring effect chain on same output thread,
7834de070137f11d346fba77605bd76a44c040a618fcEric Laurent    // so that a new chain is created with correct parameters when first effect is added. This is
7835ec35a1416472865dbebc22b10199ad718ed2cc95Eric Laurent    // otherwise unnecessary as removeEffect_l() will remove the chain when last effect is
7836de070137f11d346fba77605bd76a44c040a618fcEric Laurent    // removed.
7837de070137f11d346fba77605bd76a44c040a618fcEric Laurent    srcThread->removeEffectChain_l(chain);
7838de070137f11d346fba77605bd76a44c040a618fcEric Laurent
7839de070137f11d346fba77605bd76a44c040a618fcEric Laurent    // transfer all effects one by one so that new effect chain is created on new thread with
7840de070137f11d346fba77605bd76a44c040a618fcEric Laurent    // correct buffer sizes and audio parameters and effect engines reconfigured accordingly
784172ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten    audio_io_handle_t dstOutput = dstThread->id();
784239e94f8f723d445447fdee0822291e664b631f60Eric Laurent    sp<EffectChain> dstChain;
78433a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    uint32_t strategy = 0; // prevent compiler warning
7844de070137f11d346fba77605bd76a44c040a618fcEric Laurent    sp<EffectModule> effect = chain->getEffectFromId_l(0);
7845de070137f11d346fba77605bd76a44c040a618fcEric Laurent    while (effect != 0) {
7846de070137f11d346fba77605bd76a44c040a618fcEric Laurent        srcThread->removeEffect_l(effect);
7847de070137f11d346fba77605bd76a44c040a618fcEric Laurent        dstThread->addEffect_l(effect);
7848ec35a1416472865dbebc22b10199ad718ed2cc95Eric Laurent        // removeEffect_l() has stopped the effect if it was active so it must be restarted
7849ec35a1416472865dbebc22b10199ad718ed2cc95Eric Laurent        if (effect->state() == EffectModule::ACTIVE ||
7850ec35a1416472865dbebc22b10199ad718ed2cc95Eric Laurent                effect->state() == EffectModule::STOPPING) {
7851ec35a1416472865dbebc22b10199ad718ed2cc95Eric Laurent            effect->start();
7852ec35a1416472865dbebc22b10199ad718ed2cc95Eric Laurent        }
785339e94f8f723d445447fdee0822291e664b631f60Eric Laurent        // if the move request is not received from audio policy manager, the effect must be
785439e94f8f723d445447fdee0822291e664b631f60Eric Laurent        // re-registered with the new strategy and output
785539e94f8f723d445447fdee0822291e664b631f60Eric Laurent        if (dstChain == 0) {
785639e94f8f723d445447fdee0822291e664b631f60Eric Laurent            dstChain = effect->chain().promote();
785739e94f8f723d445447fdee0822291e664b631f60Eric Laurent            if (dstChain == 0) {
78585ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block                ALOGW("moveEffectChain_l() cannot get chain from effect %p", effect.get());
785939e94f8f723d445447fdee0822291e664b631f60Eric Laurent                srcThread->addEffect_l(effect);
786039e94f8f723d445447fdee0822291e664b631f60Eric Laurent                return NO_INIT;
786139e94f8f723d445447fdee0822291e664b631f60Eric Laurent            }
786239e94f8f723d445447fdee0822291e664b631f60Eric Laurent            strategy = dstChain->strategy();
786339e94f8f723d445447fdee0822291e664b631f60Eric Laurent        }
786439e94f8f723d445447fdee0822291e664b631f60Eric Laurent        if (reRegister) {
786539e94f8f723d445447fdee0822291e664b631f60Eric Laurent            AudioSystem::unregisterEffect(effect->id());
786639e94f8f723d445447fdee0822291e664b631f60Eric Laurent            AudioSystem::registerEffect(&effect->desc(),
786739e94f8f723d445447fdee0822291e664b631f60Eric Laurent                                        dstOutput,
786839e94f8f723d445447fdee0822291e664b631f60Eric Laurent                                        strategy,
786959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                                        sessionId,
787039e94f8f723d445447fdee0822291e664b631f60Eric Laurent                                        effect->id());
787139e94f8f723d445447fdee0822291e664b631f60Eric Laurent        }
7872de070137f11d346fba77605bd76a44c040a618fcEric Laurent        effect = chain->getEffectFromId_l(0);
7873de070137f11d346fba77605bd76a44c040a618fcEric Laurent    }
7874de070137f11d346fba77605bd76a44c040a618fcEric Laurent
7875de070137f11d346fba77605bd76a44c040a618fcEric Laurent    return NO_ERROR;
787665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
787765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
78787c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
787965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// PlaybackThread::createEffect_l() must be called with AudioFlinger::mLock held
78807c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurentsp<AudioFlinger::EffectHandle> AudioFlinger::ThreadBase::createEffect_l(
788165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        const sp<AudioFlinger::Client>& client,
788265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        const sp<IEffectClient>& effectClient,
788365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int32_t priority,
788465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int sessionId,
788565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        effect_descriptor_t *desc,
788665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int *enabled,
788765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status_t *status
788865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        )
788965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
789065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<EffectModule> effect;
789165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<EffectHandle> handle;
789265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t lStatus;
789365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<EffectChain> chain;
7894de070137f11d346fba77605bd76a44c040a618fcEric Laurent    bool chainCreated = false;
789565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool effectCreated = false;
789665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool effectRegistered = false;
789765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
78987c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    lStatus = initCheck();
78997c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (lStatus != NO_ERROR) {
79005ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("createEffect_l() Audio driver not initialized.");
790165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        goto Exit;
790265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
790365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
790465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // Do not allow effects with session ID 0 on direct output or duplicating threads
790565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // TODO: add rule for hw accelerated effects on direct outputs with non PCM format
7906fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (sessionId == AUDIO_SESSION_OUTPUT_MIX && mType != MIXER) {
79075ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("createEffect_l() Cannot add auxiliary effect %s to session %d",
7908de070137f11d346fba77605bd76a44c040a618fcEric Laurent                desc->name, sessionId);
790965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        lStatus = BAD_VALUE;
791065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        goto Exit;
791165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
79127c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    // Only Pre processor effects are allowed on input threads and only on input threads
7913a111792f1314479c649d1d44c30c2caf70c00c2aGlenn Kasten    if ((mType == RECORD) != ((desc->flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC)) {
79145ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("createEffect_l() effect %s (flags %08x) created on wrong thread type %d",
79157c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                desc->name, desc->flags, mType);
79167c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        lStatus = BAD_VALUE;
79177c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        goto Exit;
79187c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
791965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
79203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("createEffect_l() thread %p effect %s on session %d", this, desc->name, sessionId);
792165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
792265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    { // scope for mLock
792365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock _l(mLock);
792465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
792565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // check for existing effect chain with the requested audio session
792665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        chain = getEffectChain_l(sessionId);
792765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (chain == 0) {
792865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // create a new chain for this session
79293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("createEffect_l() new effect chain for session %d", sessionId);
793065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            chain = new EffectChain(this, sessionId);
793165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            addEffectChain_l(chain);
7932de070137f11d346fba77605bd76a44c040a618fcEric Laurent            chain->setStrategy(getStrategyForSession_l(sessionId));
7933de070137f11d346fba77605bd76a44c040a618fcEric Laurent            chainCreated = true;
793465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
7935cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent            effect = chain->getEffectFromDesc_l(desc);
793665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
793765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
79387fc9a6fdf146ded90b51c52f4a05d797294dcb85Glenn Kasten        ALOGV("createEffect_l() got effect %p on chain %p", effect.get(), chain.get());
793965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
794065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (effect == 0) {
79417c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            int id = mAudioFlinger->nextUniqueId();
794265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // Check CPU and memory usage
7943de070137f11d346fba77605bd76a44c040a618fcEric Laurent            lStatus = AudioSystem::registerEffect(desc, mId, chain->strategy(), sessionId, id);
794465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (lStatus != NO_ERROR) {
794565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                goto Exit;
794665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
794765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            effectRegistered = true;
794865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // create a new effect module if none present in the chain
7949de070137f11d346fba77605bd76a44c040a618fcEric Laurent            effect = new EffectModule(this, chain, desc, id, sessionId);
795065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            lStatus = effect->status();
795165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (lStatus != NO_ERROR) {
795265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                goto Exit;
795365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
7954cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent            lStatus = chain->addEffect_l(effect);
795565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (lStatus != NO_ERROR) {
795665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                goto Exit;
795765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
795865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            effectCreated = true;
795965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7960f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent            effect->setDevice(mOutDevice);
7961f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent            effect->setDevice(mInDevice);
796265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            effect->setMode(mAudioFlinger->getMode());
796357b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent            effect->setAudioSource(mAudioSource);
796465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
796565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // create effect handle and connect it to effect module
796665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        handle = new EffectHandle(effect, client, effectClient, priority);
7967a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent        lStatus = effect->addHandle(handle.get());
7968a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten        if (enabled != NULL) {
796965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            *enabled = (int)effect->isEnabled();
797065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
797165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
797265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
797365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianExit:
797465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) {
7975de070137f11d346fba77605bd76a44c040a618fcEric Laurent        Mutex::Autolock _l(mLock);
797665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (effectCreated) {
7977de070137f11d346fba77605bd76a44c040a618fcEric Laurent            chain->removeEffect_l(effect);
797865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
797965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (effectRegistered) {
7980de070137f11d346fba77605bd76a44c040a618fcEric Laurent            AudioSystem::unregisterEffect(effect->id());
7981de070137f11d346fba77605bd76a44c040a618fcEric Laurent        }
7982de070137f11d346fba77605bd76a44c040a618fcEric Laurent        if (chainCreated) {
7983de070137f11d346fba77605bd76a44c040a618fcEric Laurent            removeEffectChain_l(chain);
798465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
798565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        handle.clear();
798665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
798765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7988e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    if (status != NULL) {
798965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        *status = lStatus;
799065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
799165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return handle;
799265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
799365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7994717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurentsp<AudioFlinger::EffectModule> AudioFlinger::ThreadBase::getEffect(int sessionId, int effectId)
7995717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent{
7996717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent    Mutex::Autolock _l(mLock);
7997717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent    return getEffect_l(sessionId, effectId);
7998717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent}
7999717e128691f083a9469a1d0e363ac6ecd5c65d58Eric Laurent
80007c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurentsp<AudioFlinger::EffectModule> AudioFlinger::ThreadBase::getEffect_l(int sessionId, int effectId)
80017c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent{
80027c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    sp<EffectChain> chain = getEffectChain_l(sessionId);
8003090f01963e215f895020a31e22368cd44e086ce3Glenn Kasten    return chain != 0 ? chain->getEffectFromId_l(effectId) : 0;
80047c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent}
80057c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
8006de070137f11d346fba77605bd76a44c040a618fcEric Laurent// PlaybackThread::addEffect_l() must be called with AudioFlinger::mLock and
8007de070137f11d346fba77605bd76a44c040a618fcEric Laurent// PlaybackThread::mLock held
80087c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurentstatus_t AudioFlinger::ThreadBase::addEffect_l(const sp<EffectModule>& effect)
8009de070137f11d346fba77605bd76a44c040a618fcEric Laurent{
8010de070137f11d346fba77605bd76a44c040a618fcEric Laurent    // check for existing effect chain with the requested audio session
8011de070137f11d346fba77605bd76a44c040a618fcEric Laurent    int sessionId = effect->sessionId();
8012de070137f11d346fba77605bd76a44c040a618fcEric Laurent    sp<EffectChain> chain = getEffectChain_l(sessionId);
8013de070137f11d346fba77605bd76a44c040a618fcEric Laurent    bool chainCreated = false;
8014de070137f11d346fba77605bd76a44c040a618fcEric Laurent
8015de070137f11d346fba77605bd76a44c040a618fcEric Laurent    if (chain == 0) {
8016de070137f11d346fba77605bd76a44c040a618fcEric Laurent        // create a new chain for this session
80173856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("addEffect_l() new effect chain for session %d", sessionId);
8018de070137f11d346fba77605bd76a44c040a618fcEric Laurent        chain = new EffectChain(this, sessionId);
8019de070137f11d346fba77605bd76a44c040a618fcEric Laurent        addEffectChain_l(chain);
8020de070137f11d346fba77605bd76a44c040a618fcEric Laurent        chain->setStrategy(getStrategyForSession_l(sessionId));
8021de070137f11d346fba77605bd76a44c040a618fcEric Laurent        chainCreated = true;
8022de070137f11d346fba77605bd76a44c040a618fcEric Laurent    }
80233856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("addEffect_l() %p chain %p effect %p", this, chain.get(), effect.get());
8024de070137f11d346fba77605bd76a44c040a618fcEric Laurent
8025de070137f11d346fba77605bd76a44c040a618fcEric Laurent    if (chain->getEffectFromId_l(effect->id()) != 0) {
80265ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("addEffect_l() %p effect %s already present in chain %p",
8027de070137f11d346fba77605bd76a44c040a618fcEric Laurent                this, effect->desc().name, chain.get());
8028de070137f11d346fba77605bd76a44c040a618fcEric Laurent        return BAD_VALUE;
8029de070137f11d346fba77605bd76a44c040a618fcEric Laurent    }
8030de070137f11d346fba77605bd76a44c040a618fcEric Laurent
8031de070137f11d346fba77605bd76a44c040a618fcEric Laurent    status_t status = chain->addEffect_l(effect);
8032de070137f11d346fba77605bd76a44c040a618fcEric Laurent    if (status != NO_ERROR) {
8033de070137f11d346fba77605bd76a44c040a618fcEric Laurent        if (chainCreated) {
8034de070137f11d346fba77605bd76a44c040a618fcEric Laurent            removeEffectChain_l(chain);
8035de070137f11d346fba77605bd76a44c040a618fcEric Laurent        }
8036de070137f11d346fba77605bd76a44c040a618fcEric Laurent        return status;
8037de070137f11d346fba77605bd76a44c040a618fcEric Laurent    }
8038de070137f11d346fba77605bd76a44c040a618fcEric Laurent
8039f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent    effect->setDevice(mOutDevice);
8040f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent    effect->setDevice(mInDevice);
8041de070137f11d346fba77605bd76a44c040a618fcEric Laurent    effect->setMode(mAudioFlinger->getMode());
804257b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent    effect->setAudioSource(mAudioSource);
8043de070137f11d346fba77605bd76a44c040a618fcEric Laurent    return NO_ERROR;
8044de070137f11d346fba77605bd76a44c040a618fcEric Laurent}
8045de070137f11d346fba77605bd76a44c040a618fcEric Laurent
80467c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurentvoid AudioFlinger::ThreadBase::removeEffect_l(const sp<EffectModule>& effect) {
8047de070137f11d346fba77605bd76a44c040a618fcEric Laurent
80483856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("removeEffect_l() %p effect %p", this, effect.get());
804965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    effect_descriptor_t desc = effect->desc();
8050de070137f11d346fba77605bd76a44c040a618fcEric Laurent    if ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
8051de070137f11d346fba77605bd76a44c040a618fcEric Laurent        detachAuxEffect_l(effect->id());
8052de070137f11d346fba77605bd76a44c040a618fcEric Laurent    }
8053de070137f11d346fba77605bd76a44c040a618fcEric Laurent
8054de070137f11d346fba77605bd76a44c040a618fcEric Laurent    sp<EffectChain> chain = effect->chain().promote();
8055de070137f11d346fba77605bd76a44c040a618fcEric Laurent    if (chain != 0) {
8056de070137f11d346fba77605bd76a44c040a618fcEric Laurent        // remove effect chain if removing last effect
8057de070137f11d346fba77605bd76a44c040a618fcEric Laurent        if (chain->removeEffect_l(effect) == 0) {
8058de070137f11d346fba77605bd76a44c040a618fcEric Laurent            removeEffectChain_l(chain);
8059de070137f11d346fba77605bd76a44c040a618fcEric Laurent        }
8060de070137f11d346fba77605bd76a44c040a618fcEric Laurent    } else {
80615ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("removeEffect_l() %p cannot promote chain for effect %p", this, effect.get());
8062de070137f11d346fba77605bd76a44c040a618fcEric Laurent    }
8063de070137f11d346fba77605bd76a44c040a618fcEric Laurent}
8064de070137f11d346fba77605bd76a44c040a618fcEric Laurent
80657c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurentvoid AudioFlinger::ThreadBase::lockEffectChains_l(
8066e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        Vector< sp<AudioFlinger::EffectChain> >& effectChains)
80677c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent{
80687c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    effectChains = mEffectChains;
80697c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    for (size_t i = 0; i < mEffectChains.size(); i++) {
80707c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        mEffectChains[i]->lock();
80717c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
80727c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent}
80737c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
80747c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurentvoid AudioFlinger::ThreadBase::unlockEffectChains(
8075e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        const Vector< sp<AudioFlinger::EffectChain> >& effectChains)
80767c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent{
80777c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    for (size_t i = 0; i < effectChains.size(); i++) {
80787c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        effectChains[i]->unlock();
80797c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
80807c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent}
80817c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
80827c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurentsp<AudioFlinger::EffectChain> AudioFlinger::ThreadBase::getEffectChain(int sessionId)
80837c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent{
80847c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    Mutex::Autolock _l(mLock);
80857c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    return getEffectChain_l(sessionId);
80867c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent}
80877c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
8088106e8a42038f9e90d5ff97f8ab6f1a42258bde9eGlenn Kastensp<AudioFlinger::EffectChain> AudioFlinger::ThreadBase::getEffectChain_l(int sessionId) const
80897c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent{
80907c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    size_t size = mEffectChains.size();
80917c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    for (size_t i = 0; i < size; i++) {
80927c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        if (mEffectChains[i]->sessionId() == sessionId) {
8093090f01963e215f895020a31e22368cd44e086ce3Glenn Kasten            return mEffectChains[i];
80947c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        }
80957c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
8096090f01963e215f895020a31e22368cd44e086ce3Glenn Kasten    return 0;
80977c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent}
80987c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
8099f78aee70d15daf4690de7e7b4983ee68b0d1381dGlenn Kastenvoid AudioFlinger::ThreadBase::setMode(audio_mode_t mode)
81007c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent{
81017c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    Mutex::Autolock _l(mLock);
81027c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    size_t size = mEffectChains.size();
81037c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    for (size_t i = 0; i < size; i++) {
81047c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        mEffectChains[i]->setMode_l(mode);
81057c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
81067c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent}
81077c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
81087c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurentvoid AudioFlinger::ThreadBase::disconnectEffect(const sp<EffectModule>& effect,
8109a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent                                                    EffectHandle *handle,
811058123c3a8b5f34f9d1f70264a3c568ed90288501Glenn Kasten                                                    bool unpinIfLast) {
811159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
811265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
81133856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("disconnectEffect() %p effect %p", this, effect.get());
811465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // delete the effect module if removing last handle on it
811565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (effect->removeHandle(handle) == 0) {
811658123c3a8b5f34f9d1f70264a3c568ed90288501Glenn Kasten        if (!effect->isPinned() || unpinIfLast) {
81173a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            removeEffect_l(effect);
81183a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            AudioSystem::unregisterEffect(effect->id());
81193a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        }
812065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
812165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
812265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
812365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::PlaybackThread::addEffectChain_l(const sp<EffectChain>& chain)
812465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
812565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int session = chain->sessionId();
812665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int16_t *buffer = mMixBuffer;
812765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool ownsBuffer = false;
812865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
81293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("addEffectChain_l() %p on thread %p for session %d", chain.get(), this, session);
813065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (session > 0) {
813165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Only one effect chain can be present in direct output thread and it uses
813265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // the mix buffer as input
813365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mType != DIRECT) {
813458912562617941964939a4182cda71eaeb153d4bGlenn Kasten            size_t numSamples = mNormalFrameCount * mChannelCount;
813565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            buffer = new int16_t[numSamples];
813665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            memset(buffer, 0, numSamples * sizeof(int16_t));
81373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("addEffectChain_l() creating new input buffer %p session %d", buffer, session);
813865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            ownsBuffer = true;
813965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
814065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
814165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Attach all tracks with same session ID to this chain.
814265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (size_t i = 0; i < mTracks.size(); ++i) {
814365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            sp<Track> track = mTracks[i];
814465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (session == track->sessionId()) {
814585ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                ALOGV("addEffectChain_l() track->setMainBuffer track %p buffer %p", track.get(),
814685ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                        buffer);
814765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                track->setMainBuffer(buffer);
8148b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent                chain->incTrackCnt();
814965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
815065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
815165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
815265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // indicate all active tracks in the chain
815365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (size_t i = 0 ; i < mActiveTracks.size() ; ++i) {
815465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            sp<Track> track = mActiveTracks[i].promote();
8155d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten            if (track == 0) {
8156d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten                continue;
8157d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten            }
815865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (session == track->sessionId()) {
81593856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("addEffectChain_l() activating track %p on session %d", track.get(), session);
8160b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent                chain->incActiveTrackCnt();
816165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
816265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
816365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
816465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
816565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    chain->setInBuffer(buffer, ownsBuffer);
816665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    chain->setOutBuffer(mMixBuffer);
8167fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    // Effect chain for session AUDIO_SESSION_OUTPUT_STAGE is inserted at end of effect
8168de070137f11d346fba77605bd76a44c040a618fcEric Laurent    // chains list in order to be processed last as it contains output stage effects
8169fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    // Effect chain for session AUDIO_SESSION_OUTPUT_MIX is inserted before
8170fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    // session AUDIO_SESSION_OUTPUT_STAGE to be processed
817165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // after track specific effects and before output stage
8172fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    // It is therefore mandatory that AUDIO_SESSION_OUTPUT_MIX == 0 and
8173fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    // that AUDIO_SESSION_OUTPUT_STAGE < AUDIO_SESSION_OUTPUT_MIX
8174de070137f11d346fba77605bd76a44c040a618fcEric Laurent    // Effect chain for other sessions are inserted at beginning of effect
8175de070137f11d346fba77605bd76a44c040a618fcEric Laurent    // chains list to be processed before output mix effects. Relative order between other
8176de070137f11d346fba77605bd76a44c040a618fcEric Laurent    // sessions is not important
817765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    size_t size = mEffectChains.size();
817865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    size_t i = 0;
817965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (i = 0; i < size; i++) {
8180d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        if (mEffectChains[i]->sessionId() < session) {
8181d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten            break;
8182d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        }
818365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
818465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mEffectChains.insertAt(chain, i);
818559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    checkSuspendOnAddEffectChain_l(chain);
818665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
818765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
818865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
818965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
819065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansize_t AudioFlinger::PlaybackThread::removeEffectChain_l(const sp<EffectChain>& chain)
819165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
819265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int session = chain->sessionId();
819365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
81943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("removeEffectChain_l() %p from thread %p for session %d", chain.get(), this, session);
819565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
819665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < mEffectChains.size(); i++) {
819765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (chain == mEffectChains[i]) {
819865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mEffectChains.removeAt(i);
8199b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent            // detach all active tracks from the chain
8200b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent            for (size_t i = 0 ; i < mActiveTracks.size() ; ++i) {
8201b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent                sp<Track> track = mActiveTracks[i].promote();
8202d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten                if (track == 0) {
8203d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten                    continue;
8204d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten                }
8205b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent                if (session == track->sessionId()) {
82063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("removeEffectChain_l(): stopping track on chain %p for session Id: %d",
8207b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent                            chain.get(), session);
8208b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent                    chain->decActiveTrackCnt();
8209b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent                }
8210b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent            }
8211b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent
821265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // detach all tracks with same session ID from this chain
821365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            for (size_t i = 0; i < mTracks.size(); ++i) {
821465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                sp<Track> track = mTracks[i];
821565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (session == track->sessionId()) {
821665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    track->setMainBuffer(mMixBuffer);
8217b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent                    chain->decTrackCnt();
821865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
821965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
8220de070137f11d346fba77605bd76a44c040a618fcEric Laurent            break;
822165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
822265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
822365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mEffectChains.size();
822465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
822565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
8226de070137f11d346fba77605bd76a44c040a618fcEric Laurentstatus_t AudioFlinger::PlaybackThread::attachAuxEffect(
8227de070137f11d346fba77605bd76a44c040a618fcEric Laurent        const sp<AudioFlinger::PlaybackThread::Track> track, int EffectId)
822865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
822965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
823065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return attachAuxEffect_l(track, EffectId);
823165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
823265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
8233de070137f11d346fba77605bd76a44c040a618fcEric Laurentstatus_t AudioFlinger::PlaybackThread::attachAuxEffect_l(
8234de070137f11d346fba77605bd76a44c040a618fcEric Laurent        const sp<AudioFlinger::PlaybackThread::Track> track, int EffectId)
823565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
823665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t status = NO_ERROR;
823765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
823865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (EffectId == 0) {
823965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        track->setAuxBuffer(0, NULL);
824065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
8241fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        // Auxiliary effects are always in audio session AUDIO_SESSION_OUTPUT_MIX
8242fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        sp<EffectModule> effect = getEffect_l(AUDIO_SESSION_OUTPUT_MIX, EffectId);
824365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (effect != 0) {
824465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if ((effect->desc().flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
824565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                track->setAuxBuffer(EffectId, (int32_t *)effect->inBuffer());
824665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else {
824765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                status = INVALID_OPERATION;
824865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
824965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
825065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            status = BAD_VALUE;
825165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
825265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
825365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return status;
825465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
825565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
825665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::PlaybackThread::detachAuxEffect_l(int effectId)
825765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
8258e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    for (size_t i = 0; i < mTracks.size(); ++i) {
825965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<Track> track = mTracks[i];
826065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (track->auxEffectId() == effectId) {
826165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            attachAuxEffect_l(track, 0);
826265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
826365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
826465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
826565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
82667c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurentstatus_t AudioFlinger::RecordThread::addEffectChain_l(const sp<EffectChain>& chain)
82677c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent{
82687c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    // only one chain per input thread
82697c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (mEffectChains.size() != 0) {
82707c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        return INVALID_OPERATION;
82717c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
82723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("addEffectChain_l() %p on thread %p", chain.get(), this);
82737c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
82747c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    chain->setInBuffer(NULL);
82757c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    chain->setOutBuffer(NULL);
82767c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
827759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    checkSuspendOnAddEffectChain_l(chain);
827859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
82797c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    mEffectChains.add(chain);
82807c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
82817c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    return NO_ERROR;
82827c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent}
82837c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
82847c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurentsize_t AudioFlinger::RecordThread::removeEffectChain_l(const sp<EffectChain>& chain)
82857c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent{
82863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("removeEffectChain_l() %p from thread %p", chain.get(), this);
82875ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block    ALOGW_IF(mEffectChains.size() != 1,
82887c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            "removeEffectChain_l() %p invalid chain size %d on thread %p",
82897c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            chain.get(), mEffectChains.size(), this);
82907c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (mEffectChains.size() == 1) {
82917c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        mEffectChains.removeAt(0);
82927c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
82937c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    return 0;
82947c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent}
82957c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
829665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
829765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian//  EffectModule implementation
829865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
829965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
830065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#undef LOG_TAG
830165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define LOG_TAG "AudioFlinger::EffectModule"
830265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
83039eaa55756c5b245970447019250ce852f5189525Glenn KastenAudioFlinger::EffectModule::EffectModule(ThreadBase *thread,
830465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                        const wp<AudioFlinger::EffectChain>& chain,
830565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                        effect_descriptor_t *desc,
830665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                        int id,
830765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                        int sessionId)
8308415fa7599f48494f99206b8d6e1974abb52c5923Glenn Kasten    : mPinned(sessionId > AUDIO_SESSION_OUTPUT_MIX),
8309415fa7599f48494f99206b8d6e1974abb52c5923Glenn Kasten      mThread(thread), mChain(chain), mId(id), mSessionId(sessionId),
8310cd2d61016527bf48bd2e9a920bb3fdbb875eb3e4Glenn Kasten      mDescriptor(*desc),
8311415fa7599f48494f99206b8d6e1974abb52c5923Glenn Kasten      // mConfig is set by configure() and not used before then
8312415fa7599f48494f99206b8d6e1974abb52c5923Glenn Kasten      mEffectInterface(NULL),
8313415fa7599f48494f99206b8d6e1974abb52c5923Glenn Kasten      mStatus(NO_INIT), mState(IDLE),
8314415fa7599f48494f99206b8d6e1974abb52c5923Glenn Kasten      // mMaxDisableWaitCnt is set by configure() and not used before then
8315415fa7599f48494f99206b8d6e1974abb52c5923Glenn Kasten      // mDisableWaitCnt is set by process() and updateState() and not used before then
8316415fa7599f48494f99206b8d6e1974abb52c5923Glenn Kasten      mSuspended(false)
831765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
83183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("Constructor %p", this);
831965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int lStatus;
832065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
832165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // create effect engine from effect factory
83227c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    mStatus = EffectCreate(&desc->uuid, sessionId, thread->id(), &mEffectInterface);
832365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
832465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mStatus != NO_ERROR) {
832565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return;
832665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
832765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    lStatus = init();
832865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (lStatus < 0) {
832965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mStatus = lStatus;
833065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        goto Error;
833165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
833265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
83333856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("Constructor success name %s, Interface %p", mDescriptor.name, mEffectInterface);
833465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return;
833565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianError:
833665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    EffectRelease(mEffectInterface);
833765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mEffectInterface = NULL;
83383856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("Constructor Error %d", mStatus);
833965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
834065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
834165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::EffectModule::~EffectModule()
834265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
83433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("Destructor %p", this);
834465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mEffectInterface != NULL) {
83457c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC ||
83467c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC) {
83477c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            sp<ThreadBase> thread = mThread.promote();
83487c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            if (thread != 0) {
8349b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent                audio_stream_t *stream = thread->stream();
8350b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent                if (stream != NULL) {
8351b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent                    stream->remove_audio_effect(stream, mEffectInterface);
8352b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent                }
83537c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            }
83547c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        }
835565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // release effect engine
835665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        EffectRelease(mEffectInterface);
835765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
835865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
835965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
8360a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurentstatus_t AudioFlinger::EffectModule::addHandle(EffectHandle *handle)
836165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
836265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t status;
836365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
836465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
836565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int priority = handle->priority();
836665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    size_t size = mHandles.size();
8367a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent    EffectHandle *controlHandle = NULL;
836865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    size_t i;
836965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (i = 0; i < size; i++) {
8370a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent        EffectHandle *h = mHandles[i];
8371d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        if (h == NULL || h->destroyed_l()) {
8372d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten            continue;
8373d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        }
8374a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent        // first non destroyed handle is considered in control
8375a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent        if (controlHandle == NULL)
8376a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent            controlHandle = h;
8377d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        if (h->priority() <= priority) {
8378d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten            break;
8379d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        }
838065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
838165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // if inserted in first place, move effect control from previous owner to this handle
838265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (i == 0) {
838359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        bool enabled = false;
8384a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent        if (controlHandle != NULL) {
8385a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent            enabled = controlHandle->enabled();
8386a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent            controlHandle->setControl(false/*hasControl*/, true /*signal*/, enabled /*enabled*/);
838765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
838859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        handle->setControl(true /*hasControl*/, false /*signal*/, enabled /*enabled*/);
838965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status = NO_ERROR;
839065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
839165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status = ALREADY_EXISTS;
839265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
8393a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent    ALOGV("addHandle() %p added handle %p in position %d", this, handle, i);
839465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHandles.insertAt(handle, i);
839565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return status;
839665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
839765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
8398a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurentsize_t AudioFlinger::EffectModule::removeHandle(EffectHandle *handle)
839965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
840065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
840165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    size_t size = mHandles.size();
840265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    size_t i;
840365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (i = 0; i < size; i++) {
8404d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        if (mHandles[i] == handle) {
8405d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten            break;
8406d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        }
840765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
840865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (i == size) {
840965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return size;
841065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
8411a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent    ALOGV("removeHandle() %p removed handle %p in position %d", this, handle, i);
841259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
841365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHandles.removeAt(i);
841465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // if removed from first place, move effect control from this handle to next in line
8415a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent    if (i == 0) {
8416a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent        EffectHandle *h = controlHandle_l();
8417a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent        if (h != NULL) {
8418a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent            h->setControl(true /*hasControl*/, true /*signal*/ , handle->enabled() /*enabled*/);
841965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
842065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
842165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
8422ec437d8d3db79459d7b19e1734e6fe309bd621e8Eric Laurent    // Prevent calls to process() and other functions on effect interface from now on.
8423ec437d8d3db79459d7b19e1734e6fe309bd621e8Eric Laurent    // The effect engine will be released by the destructor when the last strong reference on
8424ec437d8d3db79459d7b19e1734e6fe309bd621e8Eric Laurent    // this object is released which can happen after next process is called.
8425a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent    if (mHandles.size() == 0 && !mPinned) {
8426ec437d8d3db79459d7b19e1734e6fe309bd621e8Eric Laurent        mState = DESTROYED;
8427dac69110ed1073bf0a9827a3f78698896dd05d97Eric Laurent    }
8428dac69110ed1073bf0a9827a3f78698896dd05d97Eric Laurent
8429e65c89113232d070dd9153c54ca19301bca7a162Eric Laurent    return mHandles.size();
843065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
843165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
8432a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent// must be called with EffectModule::mLock held
8433a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric LaurentAudioFlinger::EffectHandle *AudioFlinger::EffectModule::controlHandle_l()
843459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent{
8435a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent    // the first valid handle in the list has control over the module
8436a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent    for (size_t i = 0; i < mHandles.size(); i++) {
8437a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent        EffectHandle *h = mHandles[i];
8438a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent        if (h != NULL && !h->destroyed_l()) {
8439a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent            return h;
8440a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent        }
8441a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent    }
8442a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent
8443a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent    return NULL;
844459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent}
844559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
8446a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurentsize_t AudioFlinger::EffectModule::disconnect(EffectHandle *handle, bool unpinIfLast)
844765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
8448a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent    ALOGV("disconnect() %p handle %p", this, handle);
844965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // keep a strong reference on this EffectModule to avoid calling the
845065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // destructor before we exit
845165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<EffectModule> keep(this);
845265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    {
845365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<ThreadBase> thread = mThread.promote();
845465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (thread != 0) {
845558123c3a8b5f34f9d1f70264a3c568ed90288501Glenn Kasten            thread->disconnectEffect(keep, handle, unpinIfLast);
845665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
845765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
8458a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent    return mHandles.size();
845965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
846065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
846165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::EffectModule::updateState() {
846265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
846365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
846465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    switch (mState) {
846565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    case RESTART:
846665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        reset_l();
846765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // FALL THROUGH
846865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
846965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    case STARTING:
847065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // clear auxiliary effect input buffer for next accumulation
847165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
847265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            memset(mConfig.inputCfg.buffer.raw,
847365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                   0,
847465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                   mConfig.inputCfg.buffer.frameCount*sizeof(int32_t));
847565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
847665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        start_l();
847765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mState = ACTIVE;
847865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        break;
847965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    case STOPPING:
848065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        stop_l();
848165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mDisableWaitCnt = mMaxDisableWaitCnt;
848265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mState = STOPPED;
848365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        break;
848465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    case STOPPED:
848565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // mDisableWaitCnt is forced to 1 by process() when the engine indicates the end of the
848665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // turn off sequence.
848765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (--mDisableWaitCnt == 0) {
848865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            reset_l();
848965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mState = IDLE;
849065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
849165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        break;
8492ec437d8d3db79459d7b19e1734e6fe309bd621e8Eric Laurent    default: //IDLE , ACTIVE, DESTROYED
849365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        break;
849465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
849565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
849665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
849765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::EffectModule::process()
849865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
849965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
850065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
8501ec437d8d3db79459d7b19e1734e6fe309bd621e8Eric Laurent    if (mState == DESTROYED || mEffectInterface == NULL ||
850265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mConfig.inputCfg.buffer.raw == NULL ||
850365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mConfig.outputCfg.buffer.raw == NULL) {
850465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return;
850565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
850665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
85078f45bd725549436eeacd12ee69349e2332ed8da5Eric Laurent    if (isProcessEnabled()) {
850865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // do 32 bit to 16 bit conversion for auxiliary effect input buffer
850965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
85103b21c50ef95fe4e7ac3426ca14b365749e66ff08Glenn Kasten            ditherAndClamp(mConfig.inputCfg.buffer.s32,
851165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                        mConfig.inputCfg.buffer.s32,
8512de070137f11d346fba77605bd76a44c040a618fcEric Laurent                                        mConfig.inputCfg.buffer.frameCount/2);
851365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
851465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
851565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // do the actual processing in the effect engine
851665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int ret = (*mEffectInterface)->process(mEffectInterface,
851765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                               &mConfig.inputCfg.buffer,
851865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                               &mConfig.outputCfg.buffer);
851965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
852065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // force transition to IDLE state when engine is ready
852165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mState == STOPPED && ret == -ENODATA) {
852265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mDisableWaitCnt = 1;
852365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
852465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
852565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // clear auxiliary effect input buffer for next accumulation
852665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
852773337489229cc9b50371c7a9fcd86e9f00ea46d0Eric Laurent            memset(mConfig.inputCfg.buffer.raw, 0,
852873337489229cc9b50371c7a9fcd86e9f00ea46d0Eric Laurent                   mConfig.inputCfg.buffer.frameCount*sizeof(int32_t));
852965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
853065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_INSERT &&
853173337489229cc9b50371c7a9fcd86e9f00ea46d0Eric Laurent                mConfig.inputCfg.buffer.raw != mConfig.outputCfg.buffer.raw) {
853273337489229cc9b50371c7a9fcd86e9f00ea46d0Eric Laurent        // If an insert effect is idle and input buffer is different from output buffer,
853373337489229cc9b50371c7a9fcd86e9f00ea46d0Eric Laurent        // accumulate input onto output
853465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<EffectChain> chain = mChain.promote();
8535b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent        if (chain != 0 && chain->activeTrackCnt() != 0) {
853673337489229cc9b50371c7a9fcd86e9f00ea46d0Eric Laurent            size_t frameCnt = mConfig.inputCfg.buffer.frameCount * 2;  //always stereo here
853773337489229cc9b50371c7a9fcd86e9f00ea46d0Eric Laurent            int16_t *in = mConfig.inputCfg.buffer.s16;
853873337489229cc9b50371c7a9fcd86e9f00ea46d0Eric Laurent            int16_t *out = mConfig.outputCfg.buffer.s16;
853973337489229cc9b50371c7a9fcd86e9f00ea46d0Eric Laurent            for (size_t i = 0; i < frameCnt; i++) {
854073337489229cc9b50371c7a9fcd86e9f00ea46d0Eric Laurent                out[i] = clamp16((int32_t)out[i] + (int32_t)in[i]);
854165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
854265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
854365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
854465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
854565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
854665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::EffectModule::reset_l()
854765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
854865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mEffectInterface == NULL) {
854965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return;
855065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
855165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    (*mEffectInterface)->command(mEffectInterface, EFFECT_CMD_RESET, 0, NULL, 0, NULL);
855265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
855365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
855465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::EffectModule::configure()
855565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
855665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mEffectInterface == NULL) {
855765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NO_INIT;
855865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
855965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
856065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<ThreadBase> thread = mThread.promote();
856165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (thread == 0) {
856265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return DEAD_OBJECT;
856365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
856465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
856565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // TODO: handle configuration of effects replacing track process
8566254af180475346b6186b49c297f340c9c4817511Glenn Kasten    audio_channel_mask_t channelMask = thread->channelMask();
856765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
856865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
8569e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_MONO;
857065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
8571254af180475346b6186b49c297f340c9c4817511Glenn Kasten        mConfig.inputCfg.channels = channelMask;
857265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
8573254af180475346b6186b49c297f340c9c4817511Glenn Kasten    mConfig.outputCfg.channels = channelMask;
8574e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    mConfig.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
8575e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    mConfig.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
857665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mConfig.inputCfg.samplingRate = thread->sampleRate();
857765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mConfig.outputCfg.samplingRate = mConfig.inputCfg.samplingRate;
857865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mConfig.inputCfg.bufferProvider.cookie = NULL;
857965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mConfig.inputCfg.bufferProvider.getBuffer = NULL;
858065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mConfig.inputCfg.bufferProvider.releaseBuffer = NULL;
858165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mConfig.outputCfg.bufferProvider.cookie = NULL;
858265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mConfig.outputCfg.bufferProvider.getBuffer = NULL;
858365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mConfig.outputCfg.bufferProvider.releaseBuffer = NULL;
858465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
858565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // Insert effect:
8586fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    // - in session AUDIO_SESSION_OUTPUT_MIX or AUDIO_SESSION_OUTPUT_STAGE,
8587de070137f11d346fba77605bd76a44c040a618fcEric Laurent    // always overwrites output buffer: input buffer == output buffer
858865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // - in other sessions:
858965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    //      last effect in the chain accumulates in output buffer: input buffer != output buffer
859065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    //      other effect: overwrites output buffer: input buffer == output buffer
859165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // Auxiliary effect:
859265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    //      accumulates in output buffer: input buffer != output buffer
859365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // Therefore: accumulate <=> input buffer != output buffer
859465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mConfig.inputCfg.buffer.raw != mConfig.outputCfg.buffer.raw) {
859565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
859665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
859765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_WRITE;
859865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
859965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mConfig.inputCfg.mask = EFFECT_CONFIG_ALL;
860065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mConfig.outputCfg.mask = EFFECT_CONFIG_ALL;
860165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mConfig.inputCfg.buffer.frameCount = thread->frameCount();
860265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mConfig.outputCfg.buffer.frameCount = mConfig.inputCfg.buffer.frameCount;
860365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
86043856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("configure() %p thread %p buffer %p framecount %d",
8605de070137f11d346fba77605bd76a44c040a618fcEric Laurent            this, thread.get(), mConfig.inputCfg.buffer.raw, mConfig.inputCfg.buffer.frameCount);
8606de070137f11d346fba77605bd76a44c040a618fcEric Laurent
860765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t cmdStatus;
860825f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent    uint32_t size = sizeof(int);
860925f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent    status_t status = (*mEffectInterface)->command(mEffectInterface,
86103d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent                                                   EFFECT_CMD_SET_CONFIG,
861125f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                                   sizeof(effect_config_t),
861225f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                                   &mConfig,
861325f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                                   &size,
861425f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                                   &cmdStatus);
861565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (status == 0) {
861665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status = cmdStatus;
861765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
861865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
8619f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissen    if (status == 0 &&
8620f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissen            (memcmp(&mDescriptor.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0)) {
8621f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissen        uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2];
8622f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissen        effect_param_t *p = (effect_param_t *)buf32;
8623f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissen
8624f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissen        p->psize = sizeof(uint32_t);
8625f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissen        p->vsize = sizeof(uint32_t);
8626f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissen        size = sizeof(int);
8627f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissen        *(int32_t *)p->data = VISUALIZER_PARAM_LATENCY;
8628f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissen
8629f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissen        uint32_t latency = 0;
8630f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissen        PlaybackThread *pbt = thread->mAudioFlinger->checkPlaybackThread_l(thread->mId);
8631f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissen        if (pbt != NULL) {
8632f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissen            latency = pbt->latency_l();
8633f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissen        }
8634f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissen
8635f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissen        *((int32_t *)p->data + 1)= latency;
8636f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissen        (*mEffectInterface)->command(mEffectInterface,
8637f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissen                                     EFFECT_CMD_SET_PARAM,
8638f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissen                                     sizeof(effect_param_t) + 8,
8639f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissen                                     &buf32,
8640f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissen                                     &size,
8641f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissen                                     &cmdStatus);
8642f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissen    }
8643f06c2ed50e1db871ae9eb2bd15a196064f8c278cMarco Nelissen
864465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mMaxDisableWaitCnt = (MAX_DISABLE_TIME_MS * mConfig.outputCfg.samplingRate) /
864565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            (1000 * mConfig.outputCfg.buffer.frameCount);
864665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
864765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return status;
864865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
864965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
865065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::EffectModule::init()
865165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
865265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
865365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mEffectInterface == NULL) {
865465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NO_INIT;
865565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
865665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t cmdStatus;
865725f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent    uint32_t size = sizeof(status_t);
865825f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent    status_t status = (*mEffectInterface)->command(mEffectInterface,
865925f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                                   EFFECT_CMD_INIT,
866025f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                                   0,
866125f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                                   NULL,
866225f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                                   &size,
866325f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                                   &cmdStatus);
866465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (status == 0) {
866565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status = cmdStatus;
866665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
866765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return status;
866865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
866965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
8670ec35a1416472865dbebc22b10199ad718ed2cc95Eric Laurentstatus_t AudioFlinger::EffectModule::start()
8671ec35a1416472865dbebc22b10199ad718ed2cc95Eric Laurent{
8672ec35a1416472865dbebc22b10199ad718ed2cc95Eric Laurent    Mutex::Autolock _l(mLock);
8673ec35a1416472865dbebc22b10199ad718ed2cc95Eric Laurent    return start_l();
8674ec35a1416472865dbebc22b10199ad718ed2cc95Eric Laurent}
8675ec35a1416472865dbebc22b10199ad718ed2cc95Eric Laurent
867665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::EffectModule::start_l()
867765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
867865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mEffectInterface == NULL) {
867965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NO_INIT;
868065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
868165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t cmdStatus;
868225f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent    uint32_t size = sizeof(status_t);
868325f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent    status_t status = (*mEffectInterface)->command(mEffectInterface,
868425f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                                   EFFECT_CMD_ENABLE,
868525f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                                   0,
868625f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                                   NULL,
868725f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                                   &size,
868825f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                                   &cmdStatus);
868965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (status == 0) {
869065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status = cmdStatus;
869165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
86927c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (status == 0 &&
86937c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC ||
86947c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent             (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC)) {
86957c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        sp<ThreadBase> thread = mThread.promote();
86967c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        if (thread != 0) {
8697b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent            audio_stream_t *stream = thread->stream();
8698b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent            if (stream != NULL) {
8699b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent                stream->add_audio_effect(stream, mEffectInterface);
8700b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent            }
87017c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        }
87027c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
870365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return status;
870465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
870565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
8706ec437d8d3db79459d7b19e1734e6fe309bd621e8Eric Laurentstatus_t AudioFlinger::EffectModule::stop()
8707ec437d8d3db79459d7b19e1734e6fe309bd621e8Eric Laurent{
8708ec437d8d3db79459d7b19e1734e6fe309bd621e8Eric Laurent    Mutex::Autolock _l(mLock);
8709ec437d8d3db79459d7b19e1734e6fe309bd621e8Eric Laurent    return stop_l();
8710ec437d8d3db79459d7b19e1734e6fe309bd621e8Eric Laurent}
8711ec437d8d3db79459d7b19e1734e6fe309bd621e8Eric Laurent
871265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::EffectModule::stop_l()
871365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
871465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mEffectInterface == NULL) {
871565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NO_INIT;
871665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
871765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t cmdStatus;
871825f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent    uint32_t size = sizeof(status_t);
871925f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent    status_t status = (*mEffectInterface)->command(mEffectInterface,
872025f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                                   EFFECT_CMD_DISABLE,
872125f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                                   0,
872225f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                                   NULL,
872325f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                                   &size,
872425f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                                   &cmdStatus);
872565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (status == 0) {
872665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status = cmdStatus;
872765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
87287c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (status == 0 &&
87297c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC ||
87307c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent             (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC)) {
87317c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        sp<ThreadBase> thread = mThread.promote();
87327c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        if (thread != 0) {
8733b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent            audio_stream_t *stream = thread->stream();
8734b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent            if (stream != NULL) {
8735b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent                stream->remove_audio_effect(stream, mEffectInterface);
8736b8ba0a979067a4efb0b3819bf17770793e41c15eEric Laurent            }
87377c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        }
87387c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
873965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return status;
874065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
874165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
874225f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurentstatus_t AudioFlinger::EffectModule::command(uint32_t cmdCode,
874325f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                             uint32_t cmdSize,
874425f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                             void *pCmdData,
874525f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                             uint32_t *replySize,
874625f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                             void *pReplyData)
874765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
874865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
874926dd66e8ea7a1abf28c33196fc77822f68a718afGlenn Kasten    ALOGVV("command(), cmdCode: %d, mEffectInterface: %p", cmdCode, mEffectInterface);
875065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
8751ec437d8d3db79459d7b19e1734e6fe309bd621e8Eric Laurent    if (mState == DESTROYED || mEffectInterface == NULL) {
875265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NO_INIT;
875365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
875425f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent    status_t status = (*mEffectInterface)->command(mEffectInterface,
875525f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                                   cmdCode,
875625f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                                   cmdSize,
875725f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                                   pCmdData,
875825f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                                   replySize,
875925f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                                   pReplyData);
876065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (cmdCode != EFFECT_CMD_GET_PARAM && status == NO_ERROR) {
876125f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent        uint32_t size = (replySize == NULL) ? 0 : *replySize;
876265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (size_t i = 1; i < mHandles.size(); i++) {
8763a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent            EffectHandle *h = mHandles[i];
8764a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent            if (h != NULL && !h->destroyed_l()) {
876565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                h->commandExecuted(cmdCode, cmdSize, pCmdData, size, pReplyData);
876665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
876765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
876865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
876965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return status;
877065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
877165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
877265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::EffectModule::setEnabled(bool enabled)
877365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
877465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
8775a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent    return setEnabled_l(enabled);
8776a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent}
8777a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent
8778a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent// must be called with EffectModule::mLock held
8779a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurentstatus_t AudioFlinger::EffectModule::setEnabled_l(bool enabled)
8780a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent{
8781a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent
87823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setEnabled %p enabled %d", this, enabled);
878365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
878465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (enabled != isEnabled()) {
8785db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent        status_t status = AudioSystem::setEffectEnabled(mId, enabled);
8786db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent        if (enabled && status != NO_ERROR) {
8787db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent            return status;
8788db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent        }
8789db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent
879065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        switch (mState) {
879165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // going from disabled to enabled
879265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case IDLE:
879365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mState = STARTING;
879465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
879565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case STOPPED:
879665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mState = RESTART;
879765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
879865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case STOPPING:
879965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mState = ACTIVE;
880065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
880165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
880265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // going from enabled to disabled
880365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case RESTART:
88048f45bd725549436eeacd12ee69349e2332ed8da5Eric Laurent            mState = STOPPED;
88058f45bd725549436eeacd12ee69349e2332ed8da5Eric Laurent            break;
880665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case STARTING:
880765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mState = IDLE;
880865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
880965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case ACTIVE:
881065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mState = STOPPING;
881165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
8812ec437d8d3db79459d7b19e1734e6fe309bd621e8Eric Laurent        case DESTROYED:
8813ec437d8d3db79459d7b19e1734e6fe309bd621e8Eric Laurent            return NO_ERROR; // simply ignore as we are being destroyed
881465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
881565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (size_t i = 1; i < mHandles.size(); i++) {
8816a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent            EffectHandle *h = mHandles[i];
8817a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent            if (h != NULL && !h->destroyed_l()) {
881865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                h->setEnabled(enabled);
881965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
882065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
882165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
882265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
882365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
882465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
8825c59c004a3a6042c0990d71179f88eee2ce781e3cGlenn Kastenbool AudioFlinger::EffectModule::isEnabled() const
882665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
882765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    switch (mState) {
882865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    case RESTART:
882965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    case STARTING:
883065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    case ACTIVE:
883165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return true;
883265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    case IDLE:
883365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    case STOPPING:
883465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    case STOPPED:
8835ec437d8d3db79459d7b19e1734e6fe309bd621e8Eric Laurent    case DESTROYED:
883665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    default:
883765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return false;
883865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
883965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
884065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
8841c59c004a3a6042c0990d71179f88eee2ce781e3cGlenn Kastenbool AudioFlinger::EffectModule::isProcessEnabled() const
88428f45bd725549436eeacd12ee69349e2332ed8da5Eric Laurent{
88438f45bd725549436eeacd12ee69349e2332ed8da5Eric Laurent    switch (mState) {
88448f45bd725549436eeacd12ee69349e2332ed8da5Eric Laurent    case RESTART:
88458f45bd725549436eeacd12ee69349e2332ed8da5Eric Laurent    case ACTIVE:
88468f45bd725549436eeacd12ee69349e2332ed8da5Eric Laurent    case STOPPING:
88478f45bd725549436eeacd12ee69349e2332ed8da5Eric Laurent    case STOPPED:
88488f45bd725549436eeacd12ee69349e2332ed8da5Eric Laurent        return true;
88498f45bd725549436eeacd12ee69349e2332ed8da5Eric Laurent    case IDLE:
88508f45bd725549436eeacd12ee69349e2332ed8da5Eric Laurent    case STARTING:
8851ec437d8d3db79459d7b19e1734e6fe309bd621e8Eric Laurent    case DESTROYED:
88528f45bd725549436eeacd12ee69349e2332ed8da5Eric Laurent    default:
88538f45bd725549436eeacd12ee69349e2332ed8da5Eric Laurent        return false;
88548f45bd725549436eeacd12ee69349e2332ed8da5Eric Laurent    }
88558f45bd725549436eeacd12ee69349e2332ed8da5Eric Laurent}
88568f45bd725549436eeacd12ee69349e2332ed8da5Eric Laurent
885765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::EffectModule::setVolume(uint32_t *left, uint32_t *right, bool controller)
885865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
885965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
886065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t status = NO_ERROR;
886165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
886265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // Send volume indication if EFFECT_FLAG_VOLUME_IND is set and read back altered volume
886365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // if controller flag is set (Note that controller == TRUE => EFFECT_FLAG_VOLUME_CTRL set)
88648f45bd725549436eeacd12ee69349e2332ed8da5Eric Laurent    if (isProcessEnabled() &&
8865f997cabca292d70d078ae828e21c28e6df62995fEric Laurent            ((mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_CTRL ||
8866f997cabca292d70d078ae828e21c28e6df62995fEric Laurent            (mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_IND)) {
886765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status_t cmdStatus;
886865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        uint32_t volume[2];
886965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        uint32_t *pVolume = NULL;
887025f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent        uint32_t size = sizeof(volume);
887165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        volume[0] = *left;
887265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        volume[1] = *right;
887365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (controller) {
887465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            pVolume = volume;
887565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
887625f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent        status = (*mEffectInterface)->command(mEffectInterface,
887725f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                              EFFECT_CMD_SET_VOLUME,
887825f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                              size,
887925f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                              volume,
888025f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                              &size,
888125f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                              pVolume);
888265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (controller && status == NO_ERROR && size == sizeof(volume)) {
888365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            *left = volume[0];
888465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            *right = volume[1];
888565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
888665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
888765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return status;
888865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
888965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
8890bb4350d3b9e9485ae59e084de270f86aecef8066Glenn Kastenstatus_t AudioFlinger::EffectModule::setDevice(audio_devices_t device)
889165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
8892f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent    if (device == AUDIO_DEVICE_NONE) {
8893f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent        return NO_ERROR;
8894f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent    }
8895f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent
889665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
889765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t status = NO_ERROR;
88987c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (device && (mDescriptor.flags & EFFECT_FLAG_DEVICE_MASK) == EFFECT_FLAG_DEVICE_IND) {
8899f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent        status_t cmdStatus;
8900f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent        uint32_t size = sizeof(status_t);
8901f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent        uint32_t cmd = audio_is_output_devices(device) ? EFFECT_CMD_SET_DEVICE :
8902f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent                            EFFECT_CMD_SET_INPUT_DEVICE;
8903f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent        status = (*mEffectInterface)->command(mEffectInterface,
8904f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent                                              cmd,
8905f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent                                              sizeof(uint32_t),
8906f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent                                              &device,
8907f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent                                              &size,
8908f1c04f952916cf70407051c9f824ab84fb2b6e09Eric Laurent                                              &cmdStatus);
890965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
891065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return status;
891165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
891265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
8913f78aee70d15daf4690de7e7b4983ee68b0d1381dGlenn Kastenstatus_t AudioFlinger::EffectModule::setMode(audio_mode_t mode)
891465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
891565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
891665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t status = NO_ERROR;
891765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if ((mDescriptor.flags & EFFECT_FLAG_AUDIO_MODE_MASK) == EFFECT_FLAG_AUDIO_MODE_IND) {
891865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status_t cmdStatus;
891925f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent        uint32_t size = sizeof(status_t);
892025f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent        status = (*mEffectInterface)->command(mEffectInterface,
892125f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                              EFFECT_CMD_SET_AUDIO_MODE,
8922f78aee70d15daf4690de7e7b4983ee68b0d1381dGlenn Kasten                                              sizeof(audio_mode_t),
8923e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent                                              &mode,
892425f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                              &size,
892525f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                              &cmdStatus);
892665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (status == NO_ERROR) {
892765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            status = cmdStatus;
892865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
892965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
893065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return status;
893165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
893265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
893357b2dd1e78af53115985f18d31ec5421c9da947eEric Laurentstatus_t AudioFlinger::EffectModule::setAudioSource(audio_source_t source)
893457b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent{
893557b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent    Mutex::Autolock _l(mLock);
893657b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent    status_t status = NO_ERROR;
893757b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent    if ((mDescriptor.flags & EFFECT_FLAG_AUDIO_SOURCE_MASK) == EFFECT_FLAG_AUDIO_SOURCE_IND) {
893857b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent        uint32_t size = 0;
893957b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent        status = (*mEffectInterface)->command(mEffectInterface,
894057b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent                                              EFFECT_CMD_SET_AUDIO_SOURCE,
894157b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent                                              sizeof(audio_source_t),
894257b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent                                              &source,
894357b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent                                              &size,
894457b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent                                              NULL);
894557b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent    }
894657b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent    return status;
894757b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent}
894857b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent
894959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurentvoid AudioFlinger::EffectModule::setSuspended(bool suspended)
895059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent{
895159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    Mutex::Autolock _l(mLock);
895259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    mSuspended = suspended;
895359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent}
8954a3a854868a80fd9b9b8720e06a172754943f9417Glenn Kasten
8955a3a854868a80fd9b9b8720e06a172754943f9417Glenn Kastenbool AudioFlinger::EffectModule::suspended() const
895659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent{
895759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    Mutex::Autolock _l(mLock);
895859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    return mSuspended;
895959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent}
896059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
8961a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurentbool AudioFlinger::EffectModule::purgeHandles()
8962a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent{
8963a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent    bool enabled = false;
8964a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent    Mutex::Autolock _l(mLock);
8965a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent    for (size_t i = 0; i < mHandles.size(); i++) {
8966a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent        EffectHandle *handle = mHandles[i];
8967a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent        if (handle != NULL && !handle->destroyed_l()) {
8968a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent            handle->effect().clear();
8969a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent            if (handle->hasControl()) {
8970a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent                enabled = handle->enabled();
8971a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent            }
8972a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent        }
8973a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent    }
8974a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent    return enabled;
8975a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent}
8976a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent
8977be5f05e0fdfc4e3799653702187861a2afa072eeGlenn Kastenvoid AudioFlinger::EffectModule::dump(int fd, const Vector<String16>& args)
897865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
897965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
898065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
898165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
898265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
898365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "\tEffect ID %d:\n", mId);
898465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
898565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
898665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool locked = tryLock(mLock);
898765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // failed to lock - AudioFlinger is probably deadlocked
898865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!locked) {
898965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        result.append("\t\tCould not lock Fx mutex:\n");
899065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
899165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
899265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append("\t\tSession Status State Engine:\n");
899365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "\t\t%05d   %03d    %03d   0x%08x\n",
899465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mSessionId, mStatus, mState, (uint32_t)mEffectInterface);
899565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
899665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
899765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append("\t\tDescriptor:\n");
899865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "\t\t- UUID: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
899965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mDescriptor.uuid.timeLow, mDescriptor.uuid.timeMid, mDescriptor.uuid.timeHiAndVersion,
900085ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten            mDescriptor.uuid.clockSeq, mDescriptor.uuid.node[0], mDescriptor.uuid.node[1],
900185ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                    mDescriptor.uuid.node[2],
900265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mDescriptor.uuid.node[3],mDescriptor.uuid.node[4],mDescriptor.uuid.node[5]);
900365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
900465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "\t\t- TYPE: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
900585ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                mDescriptor.type.timeLow, mDescriptor.type.timeMid,
900685ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                    mDescriptor.type.timeHiAndVersion,
900785ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                mDescriptor.type.clockSeq, mDescriptor.type.node[0], mDescriptor.type.node[1],
900885ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                    mDescriptor.type.node[2],
900965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mDescriptor.type.node[3],mDescriptor.type.node[4],mDescriptor.type.node[5]);
901065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
9011e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    snprintf(buffer, SIZE, "\t\t- apiVersion: %08X\n\t\t- flags: %08X\n",
901265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mDescriptor.apiVersion,
901365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mDescriptor.flags);
901465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
901565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "\t\t- name: %s\n",
901665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mDescriptor.name);
901765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
901865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "\t\t- implementor: %s\n",
901965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mDescriptor.implementor);
902065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
902165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
902265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append("\t\t- Input configuration:\n");
902365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append("\t\t\tBuffer     Frames  Smp rate Channels Format\n");
902465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "\t\t\t0x%08x %05d   %05d    %08x %d\n",
902565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            (uint32_t)mConfig.inputCfg.buffer.raw,
902665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mConfig.inputCfg.buffer.frameCount,
902765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mConfig.inputCfg.samplingRate,
902865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mConfig.inputCfg.channels,
902965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mConfig.inputCfg.format);
903065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
903165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
903265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append("\t\t- Output configuration:\n");
903365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append("\t\t\tBuffer     Frames  Smp rate Channels Format\n");
903465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "\t\t\t0x%08x %05d   %05d    %08x %d\n",
903565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            (uint32_t)mConfig.outputCfg.buffer.raw,
903665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mConfig.outputCfg.buffer.frameCount,
903765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mConfig.outputCfg.samplingRate,
903865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mConfig.outputCfg.channels,
903965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mConfig.outputCfg.format);
904065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
904165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
904265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "\t\t%d Clients:\n", mHandles.size());
904365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
904465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append("\t\t\tPid   Priority Ctrl Locked client server\n");
904565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < mHandles.size(); ++i) {
9046a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent        EffectHandle *handle = mHandles[i];
9047a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent        if (handle != NULL && !handle->destroyed_l()) {
904865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            handle->dump(buffer, SIZE);
904965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            result.append(buffer);
905065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
905165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
905265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
905365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append("\n");
905465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
905565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.length());
905665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
905765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (locked) {
905865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mLock.unlock();
905965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
906065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
906165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
906265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
906365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian//  EffectHandle implementation
906465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
906565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
906665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#undef LOG_TAG
906765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define LOG_TAG "AudioFlinger::EffectHandle"
906865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
906965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::EffectHandle::EffectHandle(const sp<EffectModule>& effect,
907065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                        const sp<AudioFlinger::Client>& client,
907165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                        const sp<IEffectClient>& effectClient,
907265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                        int32_t priority)
907365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    : BnEffect(),
90743a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    mEffect(effect), mEffectClient(effectClient), mClient(client), mCblk(NULL),
9075a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent    mPriority(priority), mHasControl(false), mEnabled(false), mDestroyed(false)
907665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
90773856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("constructor %p", this);
907865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
90793a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    if (client == 0) {
90803a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        return;
90813a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    }
908265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int bufOffset = ((sizeof(effect_param_cblk_t) - 1) / sizeof(int) + 1) * sizeof(int);
908365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCblkMemory = client->heap()->allocate(EFFECT_PARAM_BUFFER_SIZE + bufOffset);
908465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mCblkMemory != 0) {
908565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mCblk = static_cast<effect_param_cblk_t *>(mCblkMemory->pointer());
908665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
9087a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten        if (mCblk != NULL) {
908865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            new(mCblk) effect_param_cblk_t();
908965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mBuffer = (uint8_t *)mCblk + bufOffset;
9090e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        }
909165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
909285ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten        ALOGE("not enough memory for Effect size=%u", EFFECT_PARAM_BUFFER_SIZE +
909385ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                sizeof(effect_param_cblk_t));
909465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return;
909565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
909665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
909765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
909865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::EffectHandle::~EffectHandle()
909965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
91003856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("Destructor %p", this);
9101a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent
9102a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent    if (mEffect == 0) {
9103a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent        mDestroyed = true;
9104a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent        return;
9105a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent    }
9106a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent    mEffect->lock();
9107a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent    mDestroyed = true;
9108a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent    mEffect->unlock();
91093a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    disconnect(false);
911065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
911165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
911265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::EffectHandle::enable()
911365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
91143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("enable %p", this);
9115d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten    if (!mHasControl) {
9116d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        return INVALID_OPERATION;
9117d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten    }
9118d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten    if (mEffect == 0) {
9119d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        return DEAD_OBJECT;
9120d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten    }
912165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
9122db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent    if (mEnabled) {
9123db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent        return NO_ERROR;
9124db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent    }
9125db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent
912659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    mEnabled = true;
912759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
912859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    sp<ThreadBase> thread = mEffect->thread().promote();
912959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    if (thread != 0) {
913059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        thread->checkSuspendOnEffectEnabled(mEffect, true, mEffect->sessionId());
913159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
913259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
913359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    // checkSuspendOnEffectEnabled() can suspend this same effect when enabled
913459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    if (mEffect->suspended()) {
913559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        return NO_ERROR;
913659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
913759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
9138db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent    status_t status = mEffect->setEnabled(true);
9139db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent    if (status != NO_ERROR) {
9140db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent        if (thread != 0) {
9141db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent            thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId());
9142db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent        }
9143db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent        mEnabled = false;
9144db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent    }
9145db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent    return status;
914665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
914765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
914865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::EffectHandle::disable()
914965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
91503856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("disable %p", this);
9151d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten    if (!mHasControl) {
9152d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        return INVALID_OPERATION;
9153d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten    }
9154d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten    if (mEffect == 0) {
9155d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        return DEAD_OBJECT;
9156d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten    }
915765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
9158db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent    if (!mEnabled) {
9159db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent        return NO_ERROR;
9160db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent    }
916159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    mEnabled = false;
916259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
916359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    if (mEffect->suspended()) {
916459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        return NO_ERROR;
916559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
916659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
916759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    status_t status = mEffect->setEnabled(false);
916859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
916959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    sp<ThreadBase> thread = mEffect->thread().promote();
917059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    if (thread != 0) {
917159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId());
917259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
917359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
917459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    return status;
917565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
917665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
917765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::EffectHandle::disconnect()
917865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
91793a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    disconnect(true);
91803a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen}
91813a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen
918258123c3a8b5f34f9d1f70264a3c568ed90288501Glenn Kastenvoid AudioFlinger::EffectHandle::disconnect(bool unpinIfLast)
91833a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen{
918458123c3a8b5f34f9d1f70264a3c568ed90288501Glenn Kasten    ALOGV("disconnect(%s)", unpinIfLast ? "true" : "false");
918565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mEffect == 0) {
918665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return;
918765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
9188a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent    // restore suspended effects if the disconnected handle was enabled and the last one.
9189a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent    if ((mEffect->disconnect(this, unpinIfLast) == 0) && mEnabled) {
9190db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent        sp<ThreadBase> thread = mEffect->thread().promote();
9191db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent        if (thread != 0) {
9192db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent            thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId());
9193db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent        }
919459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
919559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
919665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // release sp on module => module destructor can be called now
919765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mEffect.clear();
919865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mClient != 0) {
9199a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten        if (mCblk != NULL) {
92001a0ae5be3d1273cba12584b33830d859510fbf82Glenn Kasten            // unlike ~TrackBase(), mCblk is never a local new, so don't delete
92013a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            mCblk->~effect_param_cblk_t();   // destroy our shared-structure.
92023a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        }
9203dbfafaffe2e97eaf8d74ec6b6c468418a1ad2443Glenn Kasten        mCblkMemory.clear();    // free the shared memory before releasing the heap it belongs to
920498ec94c5854daccc3474758524e7f4adfe535ce0Glenn Kasten        // Client destructor must run with AudioFlinger mutex locked
920565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock _l(mClient->audioFlinger()->mLock);
920665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mClient.clear();
920765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
920865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
920965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
921025f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurentstatus_t AudioFlinger::EffectHandle::command(uint32_t cmdCode,
921125f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                             uint32_t cmdSize,
921225f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                             void *pCmdData,
921325f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                             uint32_t *replySize,
921425f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                             void *pReplyData)
921565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
921626dd66e8ea7a1abf28c33196fc77822f68a718afGlenn Kasten    ALOGVV("command(), cmdCode: %d, mHasControl: %d, mEffect: %p",
921726dd66e8ea7a1abf28c33196fc77822f68a718afGlenn Kasten            cmdCode, mHasControl, (mEffect == 0) ? 0 : mEffect.get());
921865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
921965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // only get parameter command is permitted for applications not controlling the effect
922065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!mHasControl && cmdCode != EFFECT_CMD_GET_PARAM) {
922165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return INVALID_OPERATION;
922265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
9223d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten    if (mEffect == 0) {
9224d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        return DEAD_OBJECT;
9225d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten    }
9226d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten    if (mClient == 0) {
9227d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        return INVALID_OPERATION;
9228d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten    }
922965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
923065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // handle commands that are not forwarded transparently to effect engine
923165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (cmdCode == EFFECT_CMD_SET_PARAM_COMMIT) {
923285ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten        // No need to trylock() here as this function is executed in the binder thread serving a
923385ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten        // particular client process:  no risk to block the whole media server process or mixer
923485ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten        // threads if we are stuck here
923565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock _l(mCblk->lock);
923665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mCblk->clientIndex > EFFECT_PARAM_BUFFER_SIZE ||
923765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mCblk->serverIndex > EFFECT_PARAM_BUFFER_SIZE) {
923865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mCblk->serverIndex = 0;
923965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mCblk->clientIndex = 0;
924065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return BAD_VALUE;
924165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
924265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status_t status = NO_ERROR;
924365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        while (mCblk->serverIndex < mCblk->clientIndex) {
924465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            int reply;
924525f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent            uint32_t rsize = sizeof(int);
924665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            int *p = (int *)(mBuffer + mCblk->serverIndex);
924765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            int size = *p++;
924865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (((uint8_t *)p + size) > mBuffer + mCblk->clientIndex) {
92495ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block                ALOGW("command(): invalid parameter block size");
925065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                break;
925165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
925265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            effect_param_t *param = (effect_param_t *)p;
925365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (param->psize == 0 || param->vsize == 0) {
92545ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block                ALOGW("command(): null parameter or value size");
925565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mCblk->serverIndex += size;
925665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                continue;
925765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
925825f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent            uint32_t psize = sizeof(effect_param_t) +
925925f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                             ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) +
926025f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                             param->vsize;
926125f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent            status_t ret = mEffect->command(EFFECT_CMD_SET_PARAM,
926225f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                            psize,
926325f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                            p,
926425f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                            &rsize,
926525f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                            &reply);
9266aeae3de947fa0b1e670c8472b32288962f97b4f5Eric Laurent            // stop at first error encountered
9267aeae3de947fa0b1e670c8472b32288962f97b4f5Eric Laurent            if (ret != NO_ERROR) {
926865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                status = ret;
9269aeae3de947fa0b1e670c8472b32288962f97b4f5Eric Laurent                *(int *)pReplyData = reply;
9270aeae3de947fa0b1e670c8472b32288962f97b4f5Eric Laurent                break;
9271aeae3de947fa0b1e670c8472b32288962f97b4f5Eric Laurent            } else if (reply != NO_ERROR) {
9272aeae3de947fa0b1e670c8472b32288962f97b4f5Eric Laurent                *(int *)pReplyData = reply;
9273aeae3de947fa0b1e670c8472b32288962f97b4f5Eric Laurent                break;
927465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
927565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mCblk->serverIndex += size;
927665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
927765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mCblk->serverIndex = 0;
927865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mCblk->clientIndex = 0;
927965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return status;
928065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else if (cmdCode == EFFECT_CMD_ENABLE) {
9281aeae3de947fa0b1e670c8472b32288962f97b4f5Eric Laurent        *(int *)pReplyData = NO_ERROR;
928265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return enable();
928365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else if (cmdCode == EFFECT_CMD_DISABLE) {
9284aeae3de947fa0b1e670c8472b32288962f97b4f5Eric Laurent        *(int *)pReplyData = NO_ERROR;
928565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return disable();
928665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
928765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
928865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mEffect->command(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
928965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
929065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
929159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurentvoid AudioFlinger::EffectHandle::setControl(bool hasControl, bool signal, bool enabled)
929265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
92933856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setControl %p control %d", this, hasControl);
929465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
929565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHasControl = hasControl;
929659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    mEnabled = enabled;
929759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
929865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (signal && mEffectClient != 0) {
929965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mEffectClient->controlStatusChanged(hasControl);
930065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
930165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
930265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
930325f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurentvoid AudioFlinger::EffectHandle::commandExecuted(uint32_t cmdCode,
930425f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                                 uint32_t cmdSize,
930525f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                                 void *pCmdData,
930625f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                                 uint32_t replySize,
930725f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                                                 void *pReplyData)
930865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
930965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mEffectClient != 0) {
931065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mEffectClient->commandExecuted(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
931165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
931265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
931365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
931465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
931565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
931665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::EffectHandle::setEnabled(bool enabled)
931765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
931865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mEffectClient != 0) {
931965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mEffectClient->enableStatusChanged(enabled);
932065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
932165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
932265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
932365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::EffectHandle::onTransact(
932465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
932565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
932665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return BnEffect::onTransact(code, data, reply, flags);
932765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
932865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
932965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
933065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::EffectHandle::dump(char* buffer, size_t size)
933165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
9332a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten    bool locked = mCblk != NULL && tryLock(mCblk->lock);
933365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
933465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, size, "\t\t\t%05d %05d    %01u    %01u      %05u  %05u\n",
933544deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten            (mClient == 0) ? getpid_cached : mClient->pid(),
933665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mPriority,
933765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mHasControl,
933865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            !locked,
93393a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            mCblk ? mCblk->clientIndex : 0,
93403a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen            mCblk ? mCblk->serverIndex : 0
934165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            );
934265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
934365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (locked) {
934465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mCblk->lock.unlock();
934565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
934665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
934765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
934865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#undef LOG_TAG
934965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define LOG_TAG "AudioFlinger::EffectChain"
935065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
93519eaa55756c5b245970447019250ce852f5189525Glenn KastenAudioFlinger::EffectChain::EffectChain(ThreadBase *thread,
935265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                        int sessionId)
93539eaa55756c5b245970447019250ce852f5189525Glenn Kasten    : mThread(thread), mSessionId(sessionId), mActiveTrackCnt(0), mTrackCnt(0), mTailBufferCount(0),
9354b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent      mOwnInBuffer(false), mVolumeCtrlIdx(-1), mLeftVolume(UINT_MAX), mRightVolume(UINT_MAX),
9355b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent      mNewLeftVolume(UINT_MAX), mNewRightVolume(UINT_MAX)
935665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
9357fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    mStrategy = AudioSystem::getStrategyForStream(AUDIO_STREAM_MUSIC);
93589eaa55756c5b245970447019250ce852f5189525Glenn Kasten    if (thread == NULL) {
9359544fe9b6e9325701df4ab8c1d29774fc13c4cf6cEric Laurent        return;
9360544fe9b6e9325701df4ab8c1d29774fc13c4cf6cEric Laurent    }
9361544fe9b6e9325701df4ab8c1d29774fc13c4cf6cEric Laurent    mMaxTailBuffers = ((kProcessTailDurationMs * thread->sampleRate()) / 1000) /
9362544fe9b6e9325701df4ab8c1d29774fc13c4cf6cEric Laurent                                    thread->frameCount();
936365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
936465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
936565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioFlinger::EffectChain::~EffectChain()
936665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
936765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mOwnInBuffer) {
936865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        delete mInBuffer;
936965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
937065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
937165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
937265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
937359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent// getEffectFromDesc_l() must be called with ThreadBase::mLock held
937485ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kastensp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromDesc_l(
937585ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten        effect_descriptor_t *descriptor)
937665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
937765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    size_t size = mEffects.size();
937865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
937965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < size; i++) {
938065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (memcmp(&mEffects[i]->desc().uuid, &descriptor->uuid, sizeof(effect_uuid_t)) == 0) {
9381090f01963e215f895020a31e22368cd44e086ce3Glenn Kasten            return mEffects[i];
938265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
938365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
9384090f01963e215f895020a31e22368cd44e086ce3Glenn Kasten    return 0;
938565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
938665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
938759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent// getEffectFromId_l() must be called with ThreadBase::mLock held
9388cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurentsp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromId_l(int id)
938965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
939065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    size_t size = mEffects.size();
939165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
939265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < size; i++) {
9393de070137f11d346fba77605bd76a44c040a618fcEric Laurent        // by convention, return first effect if id provided is 0 (0 is never a valid id)
9394de070137f11d346fba77605bd76a44c040a618fcEric Laurent        if (id == 0 || mEffects[i]->id() == id) {
9395090f01963e215f895020a31e22368cd44e086ce3Glenn Kasten            return mEffects[i];
939665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
939765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
9398090f01963e215f895020a31e22368cd44e086ce3Glenn Kasten    return 0;
939965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
940065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
940159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent// getEffectFromType_l() must be called with ThreadBase::mLock held
940259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurentsp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromType_l(
940359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        const effect_uuid_t *type)
940459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent{
940559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    size_t size = mEffects.size();
940659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
940759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    for (size_t i = 0; i < size; i++) {
940859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        if (memcmp(&mEffects[i]->desc().type, type, sizeof(effect_uuid_t)) == 0) {
9409090f01963e215f895020a31e22368cd44e086ce3Glenn Kasten            return mEffects[i];
941059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
941159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
9412090f01963e215f895020a31e22368cd44e086ce3Glenn Kasten    return 0;
941359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent}
941459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
941591b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurentvoid AudioFlinger::EffectChain::clearInputBuffer()
941691b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent{
941791b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent    Mutex::Autolock _l(mLock);
941891b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent    sp<ThreadBase> thread = mThread.promote();
941991b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent    if (thread == 0) {
942091b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent        ALOGW("clearInputBuffer(): cannot promote mixer thread");
942191b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent        return;
942291b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent    }
942391b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent    clearInputBuffer_l(thread);
942491b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent}
942591b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent
942691b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent// Must be called with EffectChain::mLock locked
942791b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurentvoid AudioFlinger::EffectChain::clearInputBuffer_l(sp<ThreadBase> thread)
942891b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent{
942991b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent    size_t numSamples = thread->frameCount() * thread->channelCount();
943091b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent    memset(mInBuffer, 0, numSamples * sizeof(int16_t));
943191b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent
943291b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent}
943391b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent
943465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Must be called with EffectChain::mLock locked
943565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioFlinger::EffectChain::process_l()
943665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
9437dac69110ed1073bf0a9827a3f78698896dd05d97Eric Laurent    sp<ThreadBase> thread = mThread.promote();
9438dac69110ed1073bf0a9827a3f78698896dd05d97Eric Laurent    if (thread == 0) {
94395ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("process_l(): cannot promote mixer thread");
9440dac69110ed1073bf0a9827a3f78698896dd05d97Eric Laurent        return;
9441dac69110ed1073bf0a9827a3f78698896dd05d97Eric Laurent    }
9442fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    bool isGlobalSession = (mSessionId == AUDIO_SESSION_OUTPUT_MIX) ||
9443fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin            (mSessionId == AUDIO_SESSION_OUTPUT_STAGE);
9444544fe9b6e9325701df4ab8c1d29774fc13c4cf6cEric Laurent    // always process effects unless no more tracks are on the session and the effect tail
9445544fe9b6e9325701df4ab8c1d29774fc13c4cf6cEric Laurent    // has been rendered
9446544fe9b6e9325701df4ab8c1d29774fc13c4cf6cEric Laurent    bool doProcess = true;
9447dac69110ed1073bf0a9827a3f78698896dd05d97Eric Laurent    if (!isGlobalSession) {
9448544fe9b6e9325701df4ab8c1d29774fc13c4cf6cEric Laurent        bool tracksOnSession = (trackCnt() != 0);
9449b469b9490b3cd9e0f0466d9b9ab228f6c793b82eEric Laurent
9450544fe9b6e9325701df4ab8c1d29774fc13c4cf6cEric Laurent        if (!tracksOnSession && mTailBufferCount == 0) {
9451544fe9b6e9325701df4ab8c1d29774fc13c4cf6cEric Laurent            doProcess = false;
9452544fe9b6e9325701df4ab8c1d29774fc13c4cf6cEric Laurent        }
9453544fe9b6e9325701df4ab8c1d29774fc13c4cf6cEric Laurent
9454544fe9b6e9325701df4ab8c1d29774fc13c4cf6cEric Laurent        if (activeTrackCnt() == 0) {
9455544fe9b6e9325701df4ab8c1d29774fc13c4cf6cEric Laurent            // if no track is active and the effect tail has not been rendered,
9456544fe9b6e9325701df4ab8c1d29774fc13c4cf6cEric Laurent            // the input buffer must be cleared here as the mixer process will not do it
9457544fe9b6e9325701df4ab8c1d29774fc13c4cf6cEric Laurent            if (tracksOnSession || mTailBufferCount > 0) {
945891b14c4c144d0cc957a427cffc02ba10d0615677Eric Laurent                clearInputBuffer_l(thread);
9459544fe9b6e9325701df4ab8c1d29774fc13c4cf6cEric Laurent                if (mTailBufferCount > 0) {
9460544fe9b6e9325701df4ab8c1d29774fc13c4cf6cEric Laurent                    mTailBufferCount--;
9461544fe9b6e9325701df4ab8c1d29774fc13c4cf6cEric Laurent                }
9462544fe9b6e9325701df4ab8c1d29774fc13c4cf6cEric Laurent            }
9463544fe9b6e9325701df4ab8c1d29774fc13c4cf6cEric Laurent        }
9464dac69110ed1073bf0a9827a3f78698896dd05d97Eric Laurent    }
9465dac69110ed1073bf0a9827a3f78698896dd05d97Eric Laurent
946665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    size_t size = mEffects.size();
9467544fe9b6e9325701df4ab8c1d29774fc13c4cf6cEric Laurent    if (doProcess) {
9468dac69110ed1073bf0a9827a3f78698896dd05d97Eric Laurent        for (size_t i = 0; i < size; i++) {
9469dac69110ed1073bf0a9827a3f78698896dd05d97Eric Laurent            mEffects[i]->process();
9470dac69110ed1073bf0a9827a3f78698896dd05d97Eric Laurent        }
947165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
947265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < size; i++) {
947365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mEffects[i]->updateState();
947465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
947565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
947665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
9477cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent// addEffect_l() must be called with PlaybackThread::mLock held
9478de070137f11d346fba77605bd76a44c040a618fcEric Laurentstatus_t AudioFlinger::EffectChain::addEffect_l(const sp<EffectModule>& effect)
947965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
948065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    effect_descriptor_t desc = effect->desc();
948165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    uint32_t insertPref = desc.flags & EFFECT_FLAG_INSERT_MASK;
948265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
948365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
9484de070137f11d346fba77605bd76a44c040a618fcEric Laurent    effect->setChain(this);
9485de070137f11d346fba77605bd76a44c040a618fcEric Laurent    sp<ThreadBase> thread = mThread.promote();
9486de070137f11d346fba77605bd76a44c040a618fcEric Laurent    if (thread == 0) {
9487de070137f11d346fba77605bd76a44c040a618fcEric Laurent        return NO_INIT;
9488de070137f11d346fba77605bd76a44c040a618fcEric Laurent    }
9489de070137f11d346fba77605bd76a44c040a618fcEric Laurent    effect->setThread(thread);
949065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
949165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
949265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Auxiliary effects are inserted at the beginning of mEffects vector as
949365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // they are processed first and accumulated in chain input buffer
949465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mEffects.insertAt(effect, 0);
9495de070137f11d346fba77605bd76a44c040a618fcEric Laurent
949665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // the input buffer for auxiliary effect contains mono samples in
949765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // 32 bit format. This is to avoid saturation in AudoMixer
949865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // accumulation stage. Saturation is done in EffectModule::process() before
949965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // calling the process in effect engine
950065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        size_t numSamples = thread->frameCount();
950165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int32_t *buffer = new int32_t[numSamples];
950265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        memset(buffer, 0, numSamples * sizeof(int32_t));
950365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        effect->setInBuffer((int16_t *)buffer);
950465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // auxiliary effects output samples to chain input buffer for further processing
950565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // by insert effects
950665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        effect->setOutBuffer(mInBuffer);
950765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
950865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Insert effects are inserted at the end of mEffects vector as they are processed
950965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        //  after track and auxiliary effects.
951065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Insert effect order as a function of indicated preference:
951165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        //  if EFFECT_FLAG_INSERT_EXCLUSIVE, insert in first position or reject if
951265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        //  another effect is present
951365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        //  else if EFFECT_FLAG_INSERT_FIRST, insert in first position or after the
951465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        //  last effect claiming first position
951565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        //  else if EFFECT_FLAG_INSERT_LAST, insert in last position or before the
951665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        //  first effect claiming last position
951765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        //  else if EFFECT_FLAG_INSERT_ANY insert after first or before last
951865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Reject insertion if an effect with EFFECT_FLAG_INSERT_EXCLUSIVE is
951965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // already present
952065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
95218d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten        size_t size = mEffects.size();
95228d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten        size_t idx_insert = size;
95238d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten        ssize_t idx_insert_first = -1;
95248d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten        ssize_t idx_insert_last = -1;
952565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
95268d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten        for (size_t i = 0; i < size; i++) {
952765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            effect_descriptor_t d = mEffects[i]->desc();
952865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            uint32_t iMode = d.flags & EFFECT_FLAG_TYPE_MASK;
952965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            uint32_t iPref = d.flags & EFFECT_FLAG_INSERT_MASK;
953065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (iMode == EFFECT_FLAG_TYPE_INSERT) {
953165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // check invalid effect chaining combinations
953265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (insertPref == EFFECT_FLAG_INSERT_EXCLUSIVE ||
953365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    iPref == EFFECT_FLAG_INSERT_EXCLUSIVE) {
953485ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                    ALOGW("addEffect_l() could not insert effect %s: exclusive conflict with %s",
953585ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                            desc.name, d.name);
953665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    return INVALID_OPERATION;
953765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
953865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // remember position of first insert effect and by default
953965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // select this as insert position for new effect
954065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (idx_insert == size) {
954165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    idx_insert = i;
954265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
954365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // remember position of last insert effect claiming
954465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // first position
954565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (iPref == EFFECT_FLAG_INSERT_FIRST) {
954665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    idx_insert_first = i;
954765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
954865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // remember position of first insert effect claiming
954965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // last position
955065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (iPref == EFFECT_FLAG_INSERT_LAST &&
955165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    idx_insert_last == -1) {
955265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    idx_insert_last = i;
955365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
955465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
955565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
955665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
955765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // modify idx_insert from first position if needed
955865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (insertPref == EFFECT_FLAG_INSERT_LAST) {
955965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (idx_insert_last != -1) {
956065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                idx_insert = idx_insert_last;
956165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else {
956265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                idx_insert = size;
956365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
956465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
956565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (idx_insert_first != -1) {
956665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                idx_insert = idx_insert_first + 1;
956765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
956865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
956965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
957065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // always read samples from chain input buffer
957165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        effect->setInBuffer(mInBuffer);
957265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
957365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // if last effect in the chain, output samples to chain
957465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // output buffer, otherwise to chain input buffer
957565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (idx_insert == size) {
957665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (idx_insert != 0) {
957765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mEffects[idx_insert-1]->setOutBuffer(mInBuffer);
957865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mEffects[idx_insert-1]->configure();
957965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
958065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            effect->setOutBuffer(mOutBuffer);
958165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
958265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            effect->setOutBuffer(mInBuffer);
958365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
958465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mEffects.insertAt(effect, idx_insert);
958565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
958685ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten        ALOGV("addEffect_l() effect %p, added in chain %p at rank %d", effect.get(), this,
958785ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                idx_insert);
958865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
958965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    effect->configure();
959065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
959165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
959265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
9593cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent// removeEffect_l() must be called with PlaybackThread::mLock held
9594cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurentsize_t AudioFlinger::EffectChain::removeEffect_l(const sp<EffectModule>& effect)
959565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
959665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
95978d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    size_t size = mEffects.size();
959865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    uint32_t type = effect->desc().flags & EFFECT_FLAG_TYPE_MASK;
959965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
96008d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    for (size_t i = 0; i < size; i++) {
960165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (effect == mEffects[i]) {
9602ec437d8d3db79459d7b19e1734e6fe309bd621e8Eric Laurent            // calling stop here will remove pre-processing effect from the audio HAL.
9603ec437d8d3db79459d7b19e1734e6fe309bd621e8Eric Laurent            // This is safe as we hold the EffectChain mutex which guarantees that we are not in
9604ec437d8d3db79459d7b19e1734e6fe309bd621e8Eric Laurent            // the middle of a read from audio HAL
9605ec35a1416472865dbebc22b10199ad718ed2cc95Eric Laurent            if (mEffects[i]->state() == EffectModule::ACTIVE ||
9606ec35a1416472865dbebc22b10199ad718ed2cc95Eric Laurent                    mEffects[i]->state() == EffectModule::STOPPING) {
9607ec35a1416472865dbebc22b10199ad718ed2cc95Eric Laurent                mEffects[i]->stop();
9608ec35a1416472865dbebc22b10199ad718ed2cc95Eric Laurent            }
960965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (type == EFFECT_FLAG_TYPE_AUXILIARY) {
961065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                delete[] effect->inBuffer();
961165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else {
961265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (i == size - 1 && i != 0) {
961365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mEffects[i - 1]->setOutBuffer(mOutBuffer);
961465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mEffects[i - 1]->configure();
961565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
961665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
961765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mEffects.removeAt(i);
961885ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten            ALOGV("removeEffect_l() effect %p, removed from chain %p at rank %d", effect.get(),
961985ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                    this, i);
962065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
962165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
962265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
962365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
962465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mEffects.size();
962565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
962665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
9627cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent// setDevice_l() must be called with PlaybackThread::mLock held
9628bb4350d3b9e9485ae59e084de270f86aecef8066Glenn Kastenvoid AudioFlinger::EffectChain::setDevice_l(audio_devices_t device)
962965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
963065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    size_t size = mEffects.size();
963165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < size; i++) {
963265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mEffects[i]->setDevice(device);
963365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
963465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
963565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
9636cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent// setMode_l() must be called with PlaybackThread::mLock held
9637f78aee70d15daf4690de7e7b4983ee68b0d1381dGlenn Kastenvoid AudioFlinger::EffectChain::setMode_l(audio_mode_t mode)
963865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
963965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    size_t size = mEffects.size();
964065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < size; i++) {
964165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mEffects[i]->setMode(mode);
964265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
964365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
964465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
964557b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent// setAudioSource_l() must be called with PlaybackThread::mLock held
964657b2dd1e78af53115985f18d31ec5421c9da947eEric Laurentvoid AudioFlinger::EffectChain::setAudioSource_l(audio_source_t source)
964757b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent{
964857b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent    size_t size = mEffects.size();
964957b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent    for (size_t i = 0; i < size; i++) {
965057b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent        mEffects[i]->setAudioSource(source);
965157b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent    }
965257b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent}
965357b2dd1e78af53115985f18d31ec5421c9da947eEric Laurent
9654cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent// setVolume_l() must be called with PlaybackThread::mLock held
9655cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurentbool AudioFlinger::EffectChain::setVolume_l(uint32_t *left, uint32_t *right)
965665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
965765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    uint32_t newLeft = *left;
965865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    uint32_t newRight = *right;
965965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool hasControl = false;
9660cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent    int ctrlIdx = -1;
9661cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent    size_t size = mEffects.size();
966265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
9663cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent    // first update volume controller
9664cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent    for (size_t i = size; i > 0; i--) {
96658f45bd725549436eeacd12ee69349e2332ed8da5Eric Laurent        if (mEffects[i - 1]->isProcessEnabled() &&
9666cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent            (mEffects[i - 1]->desc().flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_CTRL) {
9667cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent            ctrlIdx = i - 1;
9668f997cabca292d70d078ae828e21c28e6df62995fEric Laurent            hasControl = true;
9669cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent            break;
9670cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent        }
9671cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent    }
9672cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent
9673cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent    if (ctrlIdx == mVolumeCtrlIdx && *left == mLeftVolume && *right == mRightVolume) {
9674f997cabca292d70d078ae828e21c28e6df62995fEric Laurent        if (hasControl) {
9675f997cabca292d70d078ae828e21c28e6df62995fEric Laurent            *left = mNewLeftVolume;
9676f997cabca292d70d078ae828e21c28e6df62995fEric Laurent            *right = mNewRightVolume;
9677f997cabca292d70d078ae828e21c28e6df62995fEric Laurent        }
9678f997cabca292d70d078ae828e21c28e6df62995fEric Laurent        return hasControl;
9679cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent    }
9680cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent
9681cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent    mVolumeCtrlIdx = ctrlIdx;
9682f997cabca292d70d078ae828e21c28e6df62995fEric Laurent    mLeftVolume = newLeft;
9683f997cabca292d70d078ae828e21c28e6df62995fEric Laurent    mRightVolume = newRight;
9684cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent
9685cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent    // second get volume update from volume controller
9686cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent    if (ctrlIdx >= 0) {
9687cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent        mEffects[ctrlIdx]->setVolume(&newLeft, &newRight, true);
9688f997cabca292d70d078ae828e21c28e6df62995fEric Laurent        mNewLeftVolume = newLeft;
9689f997cabca292d70d078ae828e21c28e6df62995fEric Laurent        mNewRightVolume = newRight;
969065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
969165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // then indicate volume to all other effects in chain.
969265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // Pass altered volume to effects before volume controller
969365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // and requested volume to effects after controller
969465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    uint32_t lVol = newLeft;
969565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    uint32_t rVol = newRight;
9696cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent
969765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < size; i++) {
9698d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        if ((int)i == ctrlIdx) {
9699d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten            continue;
9700d65d73c4ae74d084751b417615a78cbe7a51372aGlenn Kasten        }
9701cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent        // this also works for ctrlIdx == -1 when there is no volume controller
9702cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent        if ((int)i > ctrlIdx) {
970365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            lVol = *left;
970465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            rVol = *right;
970565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
970665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mEffects[i]->setVolume(&lVol, &rVol, false);
970765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
970865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    *left = newLeft;
970965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    *right = newRight;
971065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
971165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return hasControl;
971265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
971365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
9714be5f05e0fdfc4e3799653702187861a2afa072eeGlenn Kastenvoid AudioFlinger::EffectChain::dump(int fd, const Vector<String16>& args)
971565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
971665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
971765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
971865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
971965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
972065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "Effects for session %d:\n", mSessionId);
972165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
972265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
972365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool locked = tryLock(mLock);
972465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // failed to lock - AudioFlinger is probably deadlocked
972565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!locked) {
972665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        result.append("\tCould not lock mutex:\n");
972765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
972865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
9729cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent    result.append("\tNum fx In buffer   Out buffer   Active tracks:\n");
9730cab112421da6e8eac19ffddbbe3d76067cffee78Eric Laurent    snprintf(buffer, SIZE, "\t%02d     0x%08x  0x%08x   %d\n",
973165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mEffects.size(),
973265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            (uint32_t)mInBuffer,
973365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            (uint32_t)mOutBuffer,
973465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mActiveTrackCnt);
973565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
973665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
973765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
973865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < mEffects.size(); ++i) {
973965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<EffectModule> effect = mEffects[i];
974065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (effect != 0) {
974165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            effect->dump(fd, args);
974265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
974365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
974465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
974565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (locked) {
974665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mLock.unlock();
974765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
974865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
974965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
975059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent// must be called with ThreadBase::mLock held
975159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurentvoid AudioFlinger::EffectChain::setEffectSuspended_l(
975259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        const effect_uuid_t *type, bool suspend)
975359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent{
975459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    sp<SuspendedEffectDesc> desc;
975559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    // use effect type UUID timelow as key as there is no real risk of identical
975659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    // timeLow fields among effect type UUIDs.
97578d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    ssize_t index = mSuspendedEffects.indexOfKey(type->timeLow);
975859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    if (suspend) {
975959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        if (index >= 0) {
976059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            desc = mSuspendedEffects.valueAt(index);
976159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        } else {
976259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            desc = new SuspendedEffectDesc();
9763a189a6883ee55cf62da1d7bf5bf5a8ab501938a4Glenn Kasten            desc->mType = *type;
976459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            mSuspendedEffects.add(type->timeLow, desc);
97653856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("setEffectSuspended_l() add entry for %08x", type->timeLow);
976659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
976759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        if (desc->mRefCount++ == 0) {
976859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            sp<EffectModule> effect = getEffectIfEnabled(type);
976959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            if (effect != 0) {
977059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                desc->mEffect = effect;
977159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                effect->setSuspended(true);
977259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                effect->setEnabled(false);
977359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            }
977459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
977559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    } else {
977659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        if (index < 0) {
977759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            return;
977859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
977959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        desc = mSuspendedEffects.valueAt(index);
978059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        if (desc->mRefCount <= 0) {
97815ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("setEffectSuspended_l() restore refcount should not be 0 %d", desc->mRefCount);
978259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            desc->mRefCount = 1;
978359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
978459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        if (--desc->mRefCount == 0) {
97853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("setEffectSuspended_l() remove entry for %08x", mSuspendedEffects.keyAt(index));
978659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            if (desc->mEffect != 0) {
978759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                sp<EffectModule> effect = desc->mEffect.promote();
978859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                if (effect != 0) {
978959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                    effect->setSuspended(false);
9790a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent                    effect->lock();
9791a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent                    EffectHandle *handle = effect->controlHandle_l();
9792a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent                    if (handle != NULL && !handle->destroyed_l()) {
9793a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent                        effect->setEnabled_l(handle->enabled());
979459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                    }
9795a5f44ebaf58911805b4fb7fb479b19fd89d2e39bEric Laurent                    effect->unlock();
979659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                }
979759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                desc->mEffect.clear();
979859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            }
979959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            mSuspendedEffects.removeItemsAt(index);
980059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
980159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
980259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent}
980359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
980459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent// must be called with ThreadBase::mLock held
980559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurentvoid AudioFlinger::EffectChain::setEffectSuspendedAll_l(bool suspend)
980659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent{
980759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    sp<SuspendedEffectDesc> desc;
980859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
98098d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    ssize_t index = mSuspendedEffects.indexOfKey((int)kKeyForSuspendAll);
981059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    if (suspend) {
981159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        if (index >= 0) {
981259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            desc = mSuspendedEffects.valueAt(index);
981359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        } else {
981459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            desc = new SuspendedEffectDesc();
981559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            mSuspendedEffects.add((int)kKeyForSuspendAll, desc);
98163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("setEffectSuspendedAll_l() add entry for 0");
981759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
981859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        if (desc->mRefCount++ == 0) {
9819d05397144be774f2f3623c754e865f51753e4e31Glenn Kasten            Vector< sp<EffectModule> > effects;
9820d05397144be774f2f3623c754e865f51753e4e31Glenn Kasten            getSuspendEligibleEffects(effects);
982159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            for (size_t i = 0; i < effects.size(); i++) {
982259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                setEffectSuspended_l(&effects[i]->desc().type, true);
982359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            }
982459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
982559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    } else {
982659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        if (index < 0) {
982759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            return;
982859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
982959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        desc = mSuspendedEffects.valueAt(index);
983059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        if (desc->mRefCount <= 0) {
98315ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("setEffectSuspendedAll_l() restore refcount should not be 0 %d", desc->mRefCount);
983259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            desc->mRefCount = 1;
983359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
983459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        if (--desc->mRefCount == 0) {
983559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            Vector<const effect_uuid_t *> types;
983659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            for (size_t i = 0; i < mSuspendedEffects.size(); i++) {
983759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                if (mSuspendedEffects.keyAt(i) == (int)kKeyForSuspendAll) {
983859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                    continue;
983959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                }
984059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                types.add(&mSuspendedEffects.valueAt(i)->mType);
984159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            }
984259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            for (size_t i = 0; i < types.size(); i++) {
984359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                setEffectSuspended_l(types[i], false);
984459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            }
984585ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten            ALOGV("setEffectSuspendedAll_l() remove entry for %08x",
984685ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten                    mSuspendedEffects.keyAt(index));
984759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            mSuspendedEffects.removeItem((int)kKeyForSuspendAll);
984859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
984959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
985059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent}
985159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
98526bffdb8b598a2399e57f6ca48660fb7bdb2490b5Eric Laurent
98536bffdb8b598a2399e57f6ca48660fb7bdb2490b5Eric Laurent// The volume effect is used for automated tests only
98546bffdb8b598a2399e57f6ca48660fb7bdb2490b5Eric Laurent#ifndef OPENSL_ES_H_
98556bffdb8b598a2399e57f6ca48660fb7bdb2490b5Eric Laurentstatic const effect_uuid_t SL_IID_VOLUME_ = { 0x09e8ede0, 0xddde, 0x11db, 0xb4f6,
98566bffdb8b598a2399e57f6ca48660fb7bdb2490b5Eric Laurent                                            { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
98576bffdb8b598a2399e57f6ca48660fb7bdb2490b5Eric Laurentconst effect_uuid_t * const SL_IID_VOLUME = &SL_IID_VOLUME_;
98586bffdb8b598a2399e57f6ca48660fb7bdb2490b5Eric Laurent#endif //OPENSL_ES_H_
98596bffdb8b598a2399e57f6ca48660fb7bdb2490b5Eric Laurent
9860db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurentbool AudioFlinger::EffectChain::isEffectEligibleForSuspend(const effect_descriptor_t& desc)
9861db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent{
9862db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent    // auxiliary effects and visualizer are never suspended on output mix
9863db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent    if ((mSessionId == AUDIO_SESSION_OUTPUT_MIX) &&
9864db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent        (((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) ||
98656bffdb8b598a2399e57f6ca48660fb7bdb2490b5Eric Laurent         (memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) ||
98666bffdb8b598a2399e57f6ca48660fb7bdb2490b5Eric Laurent         (memcmp(&desc.type, SL_IID_VOLUME, sizeof(effect_uuid_t)) == 0))) {
9867db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent        return false;
9868db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent    }
9869db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent    return true;
9870db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent}
9871db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent
987285ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kastenvoid AudioFlinger::EffectChain::getSuspendEligibleEffects(
987385ab62c4b433df3f1a9826bed1c9bec07a86c750Glenn Kasten        Vector< sp<AudioFlinger::EffectModule> > &effects)
987459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent{
9875d05397144be774f2f3623c754e865f51753e4e31Glenn Kasten    effects.clear();
987659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    for (size_t i = 0; i < mEffects.size(); i++) {
9877d05397144be774f2f3623c754e865f51753e4e31Glenn Kasten        if (isEffectEligibleForSuspend(mEffects[i]->desc())) {
9878d05397144be774f2f3623c754e865f51753e4e31Glenn Kasten            effects.add(mEffects[i]);
987959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
988059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
988159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent}
988259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
988359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurentsp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectIfEnabled(
988459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                                                            const effect_uuid_t *type)
988559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent{
9886090f01963e215f895020a31e22368cd44e086ce3Glenn Kasten    sp<EffectModule> effect = getEffectFromType_l(type);
9887090f01963e215f895020a31e22368cd44e086ce3Glenn Kasten    return effect != 0 && effect->isEnabled() ? effect : 0;
988859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent}
988959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
989059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurentvoid AudioFlinger::EffectChain::checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
989159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                                                            bool enabled)
989259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent{
98938d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    ssize_t index = mSuspendedEffects.indexOfKey(effect->desc().type.timeLow);
989459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    if (enabled) {
989559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        if (index < 0) {
989659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            // if the effect is not suspend check if all effects are suspended
989759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            index = mSuspendedEffects.indexOfKey((int)kKeyForSuspendAll);
989859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            if (index < 0) {
989959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent                return;
990059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            }
9901db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent            if (!isEffectEligibleForSuspend(effect->desc())) {
9902db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent                return;
9903db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent            }
990459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            setEffectSuspended_l(&effect->desc().type, enabled);
990559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            index = mSuspendedEffects.indexOfKey(effect->desc().type.timeLow);
9906db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent            if (index < 0) {
99075ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block                ALOGW("checkSuspendOnEffectEnabled() Fx should be suspended here!");
9908db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent                return;
9909db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent            }
991059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
99113856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("checkSuspendOnEffectEnabled() enable suspending fx %08x",
9912e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten            effect->desc().type.timeLow);
991359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        sp<SuspendedEffectDesc> desc = mSuspendedEffects.valueAt(index);
991459255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        // if effect is requested to suspended but was not yet enabled, supend it now.
991559255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        if (desc->mEffect == 0) {
991659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            desc->mEffect = effect;
991759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            effect->setEnabled(false);
991859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            effect->setSuspended(true);
991959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
992059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    } else {
992159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        if (index < 0) {
992259255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent            return;
992359255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        }
99243856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("checkSuspendOnEffectEnabled() disable restoring fx %08x",
9925e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten            effect->desc().type.timeLow);
992659255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        sp<SuspendedEffectDesc> desc = mSuspendedEffects.valueAt(index);
992759255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        desc->mEffect.clear();
992859255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent        effect->setSuspended(false);
992959255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent    }
993059255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent}
993159255e4fc7d8ff52874b85b1988dc0785140cf81Eric Laurent
993265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#undef LOG_TAG
993365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define LOG_TAG "AudioFlinger"
993465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
993565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
993665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
993765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioFlinger::onTransact(
993865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
993965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
994065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return BnAudioFlinger::onTransact(code, data, reply, flags);
994165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
994265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
994365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}; // namespace android
9944