1b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson/*
2b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson * Copyright (C) 2011 The Android Open Source Project
3b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson *
4b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson * Licensed under the Apache License, Version 2.0 (the "License");
5b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson * you may not use this file except in compliance with the License.
6b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson * You may obtain a copy of the License at
7b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson *
8b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson *      http://www.apache.org/licenses/LICENSE-2.0
9b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson *
10b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson * Unless required by applicable law or agreed to in writing, software
11b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson * distributed under the License is distributed on an "AS IS" BASIS,
12b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson * See the License for the specific language governing permissions and
14b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson * limitations under the License.
15b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson */
16b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
17b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson#include <variablespeed.h>
18b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
19b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson#include <unistd.h>
20b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson#include <stdlib.h>
21b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
22b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson#include <sola_time_scaler.h>
23b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson#include <ring_buffer.h>
24b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
25b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson#include <hlogging.h>
26b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
27b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson#include <vector>
28b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
29e863816a885b0a0e1a0930969fe3e818f68f2478Flavio Lerda#include <sys/system_properties.h>
30e863816a885b0a0e1a0930969fe3e818f68f2478Flavio Lerda
31b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// ****************************************************************************
32b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// Constants, utility methods, structures and other miscellany used throughout
33b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// this file.
34b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
35b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonnamespace {
36b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
37b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// These variables are used to determine the size of the buffer queue used by
38b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// the decoder.
39b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// This is not the same as the large buffer used to hold the uncompressed data
40b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// - for that see the member variable decodeBuffer_.
41b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// The choice of 1152 corresponds to the number of samples per mp3 frame, so is
42b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// a good choice of size for a decoding buffer in the absence of other
43b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// information (we don't know exactly what formats we will be working with).
44b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonconst size_t kNumberOfBuffersInQueue = 4;
45b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonconst size_t kNumberOfSamplesPerBuffer = 1152;
46b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonconst size_t kBufferSizeInBytes = 2 * kNumberOfSamplesPerBuffer;
47b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonconst size_t kSampleSizeInBytes = 4;
48b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
49b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// When calculating play buffer size before pushing to audio player.
50b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonconst size_t kNumberOfBytesPerInt16 = 2;
51b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
52b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// How long to sleep during the main play loop and the decoding callback loop.
53b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// In due course this should be replaced with the better signal and wait on
54b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// condition rather than busy-looping.
55b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonconst int kSleepTimeMicros = 1000;
56b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
57b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// Used in detecting errors with the OpenSL ES framework.
58b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonconst SLuint32 kPrefetchErrorCandidate =
59b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE;
60b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
61b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// Structure used when we perform a decoding callback.
62b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsontypedef struct CallbackContext_ {
630bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  // Pointer to local storage buffers for decoded audio data.
640bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  int8_t* pDataBase;
650bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  // Pointer to the current buffer within local storage.
660bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  int8_t* pData;
670bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  // Used to read the sample rate and channels from the decoding stream during
680bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  // the first decoding callback.
690bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  SLMetadataExtractionItf decoderMetadata;
700bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  // The play interface used for reading duration.
710bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  SLPlayItf playItf;
72b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson} CallbackContext;
73b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
74b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// Local storage for decoded audio data.
75b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonint8_t pcmData[kNumberOfBuffersInQueue * kBufferSizeInBytes];
76b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
77b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson#define CheckSLResult(message, result) \
78b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    CheckSLResult_Real(message, result, __LINE__)
79b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
80b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// Helper function for debugging - checks the OpenSL result for success.
81b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonvoid CheckSLResult_Real(const char* message, SLresult result, int line) {
82b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // This can be helpful when debugging.
83b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // LOGD("sl result %d for %s", result, message);
84b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  if (SL_RESULT_SUCCESS != result) {
85b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    LOGE("slresult was %d at %s file variablespeed line %d",
86b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson        static_cast<int>(result), message, line);
87b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  }
88b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  CHECK(SL_RESULT_SUCCESS == result);
89b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
90b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
91e863816a885b0a0e1a0930969fe3e818f68f2478Flavio Lerda// Whether logging should be enabled. Only used if LOG_OPENSL_API_CALL is
92e863816a885b0a0e1a0930969fe3e818f68f2478Flavio Lerda// defined to use it.
93e863816a885b0a0e1a0930969fe3e818f68f2478Flavio Lerdabool gLogEnabled = false;
94e863816a885b0a0e1a0930969fe3e818f68f2478Flavio Lerda// The property to set in order to enable logging.
95e863816a885b0a0e1a0930969fe3e818f68f2478Flavio Lerdaconst char *const kLogTagVariableSpeed = "log.tag.VariableSpeed";
96e863816a885b0a0e1a0930969fe3e818f68f2478Flavio Lerda
97e863816a885b0a0e1a0930969fe3e818f68f2478Flavio Lerdabool ShouldLog() {
98e863816a885b0a0e1a0930969fe3e818f68f2478Flavio Lerda  char buffer[PROP_VALUE_MAX];
99e863816a885b0a0e1a0930969fe3e818f68f2478Flavio Lerda  __system_property_get(kLogTagVariableSpeed, buffer);
100e863816a885b0a0e1a0930969fe3e818f68f2478Flavio Lerda  return strlen(buffer) > 0;
101e863816a885b0a0e1a0930969fe3e818f68f2478Flavio Lerda}
102e863816a885b0a0e1a0930969fe3e818f68f2478Flavio Lerda
103b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}  // namespace
104b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
105b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// ****************************************************************************
106b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// Static instance of audio engine, and methods for getting, setting and
107b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// deleting it.
108b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
109b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// The single global audio engine instance.
110b83ad73794088498d6d38cd3b4fc9311f505d051Hugo HudsonAudioEngine* AudioEngine::audioEngine_ = NULL;
111b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonandroid::Mutex publishEngineLock_;
112b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
113b83ad73794088498d6d38cd3b4fc9311f505d051Hugo HudsonAudioEngine* AudioEngine::GetEngine() {
114b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  android::Mutex::Autolock autoLock(publishEngineLock_);
115b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  if (audioEngine_ == NULL) {
116b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    LOGE("you haven't initialized the audio engine");
117b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    CHECK(false);
118b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    return NULL;
119b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  }
120b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  return audioEngine_;
121b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
122b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
123b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonvoid AudioEngine::SetEngine(AudioEngine* engine) {
124b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  if (audioEngine_ != NULL) {
125b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    LOGE("you have already set the audio engine");
126b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    CHECK(false);
127b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    return;
128b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  }
129b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  audioEngine_ = engine;
130b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
131b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
132b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonvoid AudioEngine::DeleteEngine() {
133b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  if (audioEngine_ == NULL) {
134b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    LOGE("you haven't initialized the audio engine");
135b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    CHECK(false);
136b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    return;
137b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  }
138b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  delete audioEngine_;
139b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  audioEngine_ = NULL;
140b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
141b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
142b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// ****************************************************************************
143b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// The callbacks from the engine require static callback functions.
144b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// Here are the static functions - they just delegate to instance methods on
145b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// the engine.
146b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
147b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonstatic void PlayingBufferQueueCb(SLAndroidSimpleBufferQueueItf, void*) {
148b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  AudioEngine::GetEngine()->PlayingBufferQueueCallback();
149b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
150b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
151b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonstatic void PrefetchEventCb(SLPrefetchStatusItf caller, void*, SLuint32 event) {
152b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  AudioEngine::GetEngine()->PrefetchEventCallback(caller, event);
153b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
154b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
155b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonstatic void DecodingBufferQueueCb(SLAndroidSimpleBufferQueueItf queueItf,
156b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    void *context) {
157b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  AudioEngine::GetEngine()->DecodingBufferQueueCallback(queueItf, context);
158b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
159b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
160b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonstatic void DecodingEventCb(SLPlayItf caller, void*, SLuint32 event) {
161b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  AudioEngine::GetEngine()->DecodingEventCallback(caller, event);
162b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
163b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
164b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// ****************************************************************************
1650bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson// Macros for making working with OpenSL easier.
1660bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson
167e863816a885b0a0e1a0930969fe3e818f68f2478Flavio Lerda// Log based on the value of a property.
168e863816a885b0a0e1a0930969fe3e818f68f2478Flavio Lerda#define LOG_OPENSL_API_CALL(string) (gLogEnabled && LOGV(string))
169b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
1700bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson// The regular macro: log an api call, make the api call, check the result.
1710bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson#define OpenSL(obj, method, ...) \
1720bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson{ \
1730bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  LOG_OPENSL_API_CALL("OpenSL " #method "(" #obj ", " #__VA_ARGS__ ")"); \
1740bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  SLresult result = (*obj)->method(obj, __VA_ARGS__); \
1750bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  CheckSLResult("OpenSL " #method "(" #obj ", " #__VA_ARGS__ ")", result); \
176b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
177b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
1780bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson// Special case call for api call that has void return value, can't be checked.
1790bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson#define VoidOpenSL(obj, method) \
1800bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson{ \
1810bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  LOG_OPENSL_API_CALL("OpenSL (void) " #method "(" #obj ")"); \
1820bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  (*obj)->method(obj); \
183b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
184b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
1850bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson// Special case for api call with checked result but takes no arguments.
1860bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson#define OpenSL0(obj, method) \
1870bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson{ \
1880bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  LOG_OPENSL_API_CALL("OpenSL " #method "(" #obj ")"); \
1890bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  SLresult result = (*obj)->method(obj); \
1900bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  CheckSLResult("OpenSL " #method "(" #obj ")", result); \
191b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
192b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
1930bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson// Special case for api call whose result we want to store, not check.
1940bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson// We have to encapsulate the two calls in braces, so that this expression
1950bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson// evaluates to the last expression not the first.
1960bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson#define ReturnOpenSL(obj, method, ...) \
1970bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson( \
1980bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    LOG_OPENSL_API_CALL("OpenSL (int) " \
1990bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson        #method "(" #obj ", " #__VA_ARGS__ ")"), \
2000bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    (*obj)->method(obj, __VA_ARGS__) \
2010bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson) \
2020bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson
2030bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson// ****************************************************************************
2040bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson// Static utility methods.
2050bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson
206dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda// Set the audio stream type for the player.
207dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda//
208dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda// Must be called before it is realized.
209dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda//
210dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda// The caller must have requested the SL_IID_ANDROIDCONFIGURATION interface when
211dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda// creating the player.
212dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerdastatic void setAudioStreamType(SLObjectItf audioPlayer, SLint32 audioStreamType) {
213dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda  SLAndroidConfigurationItf playerConfig;
214dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda  OpenSL(audioPlayer, GetInterface, SL_IID_ANDROIDCONFIGURATION, &playerConfig);
215dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda  // The STREAM_XXX constants defined by android.media.AudioManager match the
216dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda  // corresponding SL_ANDROID_STREAM_XXX constants defined by
217dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda  // include/SLES/OpenSLES_AndroidConfiguration.h, so we can just pass the
218dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda  // value across.
219dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda  OpenSL(playerConfig, SetConfiguration, SL_ANDROID_KEY_STREAM_TYPE,
220dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda         &audioStreamType, sizeof(audioStreamType));
221dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda}
222dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda
2230bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson// Must be called with callbackLock_ held.
2240bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudsonstatic void ReadSampleRateAndChannelCount(CallbackContext *pContext,
2250bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    SLuint32 *sampleRateOut, SLuint32 *channelsOut) {
2260bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  SLMetadataExtractionItf decoderMetadata = pContext->decoderMetadata;
227b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  SLuint32 itemCount;
2280bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  OpenSL(decoderMetadata, GetItemCount, &itemCount);
229b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  SLuint32 i, keySize, valueSize;
230b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  SLMetadataInfo *keyInfo, *value;
2310bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  for (i = 0; i < itemCount; ++i) {
2320bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    keyInfo = value = NULL;
2330bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    keySize = valueSize = 0;
2340bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    OpenSL(decoderMetadata, GetKeySize, i, &keySize);
235b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    keyInfo = static_cast<SLMetadataInfo*>(malloc(keySize));
236b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    if (keyInfo) {
2370bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson      OpenSL(decoderMetadata, GetKey, i, keySize, keyInfo);
238b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      if (keyInfo->encoding == SL_CHARACTERENCODING_ASCII
239b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson          || keyInfo->encoding == SL_CHARACTERENCODING_UTF8) {
2400bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson        OpenSL(decoderMetadata, GetValueSize, i, &valueSize);
241b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson        value = static_cast<SLMetadataInfo*>(malloc(valueSize));
242b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson        if (value) {
2430bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson          OpenSL(decoderMetadata, GetValue, i, valueSize, value);
244efaa38a16baad0f8665ac23f8e0a8ba166daf75dHugo Hudson          if (strcmp((char*) keyInfo->data, ANDROID_KEY_PCMFORMAT_SAMPLERATE) == 0) {
2450bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson            SLuint32 sampleRate = *(reinterpret_cast<SLuint32*>(value->data));
2460bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson            LOGD("sample Rate: %d", sampleRate);
2470bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson            *sampleRateOut = sampleRate;
248efaa38a16baad0f8665ac23f8e0a8ba166daf75dHugo Hudson          } else if (strcmp((char*) keyInfo->data, ANDROID_KEY_PCMFORMAT_NUMCHANNELS) == 0) {
2490bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson            SLuint32 channels = *(reinterpret_cast<SLuint32*>(value->data));
2500bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson            LOGD("channels: %d", channels);
2510bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson            *channelsOut = channels;
252b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson          }
253b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson          free(value);
254b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson        }
255b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      }
256b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      free(keyInfo);
257b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    }
258b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  }
259b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
260b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
2610bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson// Must be called with callbackLock_ held.
262b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonstatic void RegisterCallbackContextAndAddEnqueueBuffersToDecoder(
2630bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    SLAndroidSimpleBufferQueueItf decoderQueue, CallbackContext* context) {
2640bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  // Register a callback on the decoder queue, so that we will be called
265b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // throughout the decoding process (and can then extract the decoded audio
266b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // for the next bit of the pipeline).
2670bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  OpenSL(decoderQueue, RegisterCallback, DecodingBufferQueueCb, context);
268b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
269b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // Enqueue buffers to map the region of memory allocated to store the
270b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // decoded data.
271b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  for (size_t i = 0; i < kNumberOfBuffersInQueue; i++) {
2720bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    OpenSL(decoderQueue, Enqueue, context->pData, kBufferSizeInBytes);
2739730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    context->pData += kBufferSizeInBytes;
274b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  }
2759730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson  context->pData = context->pDataBase;
276b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
277b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
278b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// ****************************************************************************
279b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// Constructor and Destructor.
280b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
2810bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo HudsonAudioEngine::AudioEngine(size_t targetFrames, float windowDuration,
2820bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    float windowOverlapDuration, size_t maxPlayBufferCount, float initialRate,
283dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda    size_t decodeInitialSize, size_t decodeMaxSize, size_t startPositionMillis,
284dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda    int audioStreamType)
285b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    : decodeBuffer_(decodeInitialSize, decodeMaxSize),
286b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      playingBuffers_(), freeBuffers_(), timeScaler_(NULL),
287b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      floatBuffer_(NULL), injectBuffer_(NULL),
2880bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson      mSampleRate(0), mChannels(0),
289b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      targetFrames_(targetFrames),
290b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      windowDuration_(windowDuration),
291b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      windowOverlapDuration_(windowOverlapDuration),
292b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      maxPlayBufferCount_(maxPlayBufferCount), initialRate_(initialRate),
293b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      startPositionMillis_(startPositionMillis),
294dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda      audioStreamType_(audioStreamType),
2950bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson      totalDurationMs_(0), decoderCurrentPosition_(0), startRequested_(false),
296b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      stopRequested_(false), finishedDecoding_(false) {
297e863816a885b0a0e1a0930969fe3e818f68f2478Flavio Lerda  // Determine whether we should log calls.
298e863816a885b0a0e1a0930969fe3e818f68f2478Flavio Lerda  gLogEnabled = ShouldLog();
299b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
300b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
301b83ad73794088498d6d38cd3b4fc9311f505d051Hugo HudsonAudioEngine::~AudioEngine() {
302b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // destroy the time scaler
303b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  if (timeScaler_ != NULL) {
304b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    delete timeScaler_;
305b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    timeScaler_ = NULL;
306b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  }
307b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
308b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // delete all outstanding playing and free buffers
309b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  android::Mutex::Autolock autoLock(playBufferLock_);
310b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  while (playingBuffers_.size() > 0) {
311b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    delete[] playingBuffers_.front();
312b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    playingBuffers_.pop();
313b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  }
314b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  while (freeBuffers_.size() > 0) {
315b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    delete[] freeBuffers_.top();
316b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    freeBuffers_.pop();
317b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  }
318b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
319b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  delete[] floatBuffer_;
320b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  floatBuffer_ = NULL;
321b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  delete[] injectBuffer_;
322b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  injectBuffer_ = NULL;
323b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
324b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
325b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// ****************************************************************************
326b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// Regular AudioEngine class methods.
327b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
328b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonvoid AudioEngine::SetVariableSpeed(float speed) {
3290bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  // TODO: Mutex for shared time scaler accesses.
33064f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson  if (HasSampleRateAndChannels()) {
33164f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson    GetTimeScaler()->set_speed(speed);
33264f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson  } else {
33364f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson    // This is being called at a point where we have not yet processed enough
33464f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson    // data to determine the sample rate and number of channels.
33564f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson    // Ignore the call.  See http://b/5140693.
33664f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson    LOGD("set varaible speed called, sample rate and channels not ready yet");
33764f5ba670d215847192b4ff46dc4538565f2f551Hugo Hudson  }
338b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
339b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
340b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonvoid AudioEngine::RequestStart() {
341b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  android::Mutex::Autolock autoLock(lock_);
342b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  startRequested_ = true;
343b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
344b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
345b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonvoid AudioEngine::ClearRequestStart() {
346b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  android::Mutex::Autolock autoLock(lock_);
347b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  startRequested_ = false;
348b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
349b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
350b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonbool AudioEngine::GetWasStartRequested() {
351b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  android::Mutex::Autolock autoLock(lock_);
352b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  return startRequested_;
353b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
354b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
355b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonvoid AudioEngine::RequestStop() {
356b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  android::Mutex::Autolock autoLock(lock_);
357b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  stopRequested_ = true;
358b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
359b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
360b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonint AudioEngine::GetCurrentPosition() {
361b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  android::Mutex::Autolock autoLock(decodeBufferLock_);
362b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  double result = decodeBuffer_.GetTotalAdvancedCount();
3630bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  // TODO: This is horrible, but should be removed soon once the outstanding
3640bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  // issue with get current position on decoder is fixed.
3650bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  android::Mutex::Autolock autoLock2(callbackLock_);
366b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  return static_cast<int>(
3670bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson      (result * 1000) / mSampleRate / mChannels + startPositionMillis_);
368b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
369b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
370b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonint AudioEngine::GetTotalDuration() {
371b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  android::Mutex::Autolock autoLock(lock_);
372b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  return static_cast<int>(totalDurationMs_);
373b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
374b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
375b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonvideo_editing::SolaTimeScaler* AudioEngine::GetTimeScaler() {
376b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  if (timeScaler_ == NULL) {
3770bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    CHECK(HasSampleRateAndChannels());
3780bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    android::Mutex::Autolock autoLock(callbackLock_);
379b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    timeScaler_ = new video_editing::SolaTimeScaler();
3800bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    timeScaler_->Init(mSampleRate, mChannels, initialRate_, windowDuration_,
381b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson        windowOverlapDuration_);
382b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  }
383b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  return timeScaler_;
384b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
385b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
386b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonbool AudioEngine::EnqueueNextBufferOfAudio(
387b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    SLAndroidSimpleBufferQueueItf audioPlayerQueue) {
3880bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  size_t channels;
3890bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  {
3900bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    android::Mutex::Autolock autoLock(callbackLock_);
3910bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    channels = mChannels;
3920bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  }
3930bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  size_t frameSizeInBytes = kSampleSizeInBytes * channels;
394b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  size_t frameCount = 0;
395b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  while (frameCount < targetFrames_) {
396b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    size_t framesLeft = targetFrames_ - frameCount;
397b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    // If there is data already in the time scaler, retrieve it.
398b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    if (GetTimeScaler()->available() > 0) {
399b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      size_t retrieveCount = min(GetTimeScaler()->available(), framesLeft);
400b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      int count = GetTimeScaler()->RetrieveSamples(
4010bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson          floatBuffer_ + frameCount * channels, retrieveCount);
402b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      if (count <= 0) {
4030bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson        LOGD("error: count was %d", count);
404b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson        break;
405b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      }
406b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      frameCount += count;
407b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      continue;
408b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    }
409b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    // If there is no data in the time scaler, then feed some into it.
410b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    android::Mutex::Autolock autoLock(decodeBufferLock_);
411b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    size_t framesInDecodeBuffer =
412b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson        decodeBuffer_.GetSizeInBytes() / frameSizeInBytes;
413b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    size_t framesScalerCanHandle = GetTimeScaler()->input_limit();
414b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    size_t framesToInject = min(framesInDecodeBuffer,
415b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson        min(targetFrames_, framesScalerCanHandle));
416b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    if (framesToInject <= 0) {
417b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      // No more frames left to inject.
418b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      break;
419b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    }
4200bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    for (size_t i = 0; i < framesToInject * channels; ++i) {
421b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      injectBuffer_[i] = decodeBuffer_.GetAtIndex(i);
422b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    }
423b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    int count = GetTimeScaler()->InjectSamples(injectBuffer_, framesToInject);
424b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    if (count <= 0) {
4250bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson      LOGD("error: count was %d", count);
426b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      break;
427b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    }
4280bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    decodeBuffer_.AdvanceHeadPointerShorts(count * channels);
429b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  }
430b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  if (frameCount <= 0) {
431b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    // We must have finished playback.
432b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    if (GetEndOfDecoderReached()) {
433b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      // If we've finished decoding, clear the buffer - so we will terminate.
434b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      ClearDecodeBuffer();
435b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    }
436b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    return false;
437b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  }
438b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
439b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // Get a free playing buffer.
440b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  int16* playBuffer;
441b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  {
442b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    android::Mutex::Autolock autoLock(playBufferLock_);
443b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    if (freeBuffers_.size() > 0) {
444b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      // If we have a free buffer, recycle it.
445b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      playBuffer = freeBuffers_.top();
446b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      freeBuffers_.pop();
447b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    } else {
448b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      // Otherwise allocate a new one.
4490bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson      playBuffer = new int16[targetFrames_ * channels];
450b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    }
451b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  }
452b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
453b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // Try to play the buffer.
4540bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  for (size_t i = 0; i < frameCount * channels; ++i) {
455b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    playBuffer[i] = floatBuffer_[i];
456b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  }
457b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  size_t sizeOfPlayBufferInBytes =
4580bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson      frameCount * channels * kNumberOfBytesPerInt16;
4590bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  SLresult result = ReturnOpenSL(audioPlayerQueue, Enqueue, playBuffer,
460b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      sizeOfPlayBufferInBytes);
461b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  if (result == SL_RESULT_SUCCESS) {
462b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    android::Mutex::Autolock autoLock(playBufferLock_);
463b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    playingBuffers_.push(playBuffer);
464b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  } else {
465b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    LOGE("could not enqueue audio buffer");
466b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    delete[] playBuffer;
467b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  }
468b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
469b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  return (result == SL_RESULT_SUCCESS);
470b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
471b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
472b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonbool AudioEngine::GetEndOfDecoderReached() {
473b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  android::Mutex::Autolock autoLock(lock_);
474b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  return finishedDecoding_;
475b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
476b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
477b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonvoid AudioEngine::SetEndOfDecoderReached() {
478b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  android::Mutex::Autolock autoLock(lock_);
479b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  finishedDecoding_ = true;
480b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
481b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
482b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonbool AudioEngine::PlayFileDescriptor(int fd, int64 offset, int64 length) {
483b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  SLDataLocator_AndroidFD loc_fd = {
484b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      SL_DATALOCATOR_ANDROIDFD, fd, offset, length };
485b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  SLDataFormat_MIME format_mime = {
486b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED };
487b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  SLDataSource audioSrc = { &loc_fd, &format_mime };
488b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  return PlayFromThisSource(audioSrc);
489b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
490b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
491b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonbool AudioEngine::PlayUri(const char* uri) {
492b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // Source of audio data for the decoding
493b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  SLDataLocator_URI decUri = { SL_DATALOCATOR_URI,
494b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      const_cast<SLchar*>(reinterpret_cast<const SLchar*>(uri)) };
495b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  SLDataFormat_MIME decMime = {
496b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED };
497b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  SLDataSource decSource = { &decUri, &decMime };
498b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  return PlayFromThisSource(decSource);
499b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
500b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
501b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonbool AudioEngine::IsDecodeBufferEmpty() {
502b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  android::Mutex::Autolock autoLock(decodeBufferLock_);
503b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  return decodeBuffer_.GetSizeInBytes() <= 0;
504b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
505b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
506b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonvoid AudioEngine::ClearDecodeBuffer() {
507b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  android::Mutex::Autolock autoLock(decodeBufferLock_);
508b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  decodeBuffer_.Clear();
509b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
510b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
5110bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudsonstatic size_t ReadDuration(SLPlayItf playItf) {
5120bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  SLmillisecond durationInMsec = SL_TIME_UNKNOWN;
5130bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  OpenSL(playItf, GetDuration, &durationInMsec);
5140bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  if (durationInMsec == SL_TIME_UNKNOWN) {
5150bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    LOGE("can't get duration");
5160bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    return 0;
5170bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  }
5180bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  LOGD("duration: %d", static_cast<int>(durationInMsec));
5190bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  return durationInMsec;
5200bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson}
5210bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson
5220bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudsonstatic size_t ReadPosition(SLPlayItf playItf) {
5230bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  SLmillisecond positionInMsec = SL_TIME_UNKNOWN;
5240bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  OpenSL(playItf, GetPosition, &positionInMsec);
5250bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  if (positionInMsec == SL_TIME_UNKNOWN) {
5260bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    LOGE("can't get position");
5270bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    return 0;
5280bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  }
5290bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  LOGW("decoder position: %d", static_cast<int>(positionInMsec));
5300bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  return positionInMsec;
5310bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson}
5320bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson
5339730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudsonstatic void CreateAndRealizeEngine(SLObjectItf &engine,
5349730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    SLEngineItf &engineInterface) {
535b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  SLEngineOption EngineOption[] = { {
536b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      SL_ENGINEOPTION_THREADSAFE, SL_BOOLEAN_TRUE } };
537b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  SLresult result = slCreateEngine(&engine, 1, EngineOption, 0, NULL, NULL);
538b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  CheckSLResult("create engine", result);
5390bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  OpenSL(engine, Realize, SL_BOOLEAN_FALSE);
5400bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  OpenSL(engine, GetInterface, SL_IID_ENGINE, &engineInterface);
5419730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson}
542b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
5430bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo HudsonSLuint32 AudioEngine::GetSLSampleRate() {
5440bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  android::Mutex::Autolock autoLock(callbackLock_);
5450bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  return mSampleRate * 1000;
5469730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson}
5479730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
5480bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo HudsonSLuint32 AudioEngine::GetSLChannels() {
5490bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  android::Mutex::Autolock autoLock(callbackLock_);
5500bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  switch (mChannels) {
5519730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    case 2:
5520bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson      return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
5539730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    case 1:
5540bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson      return SL_SPEAKER_FRONT_CENTER;
5559730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    default:
5560bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson      LOGE("unknown channels %d, using 2", mChannels);
5570bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson      return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
5589730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson  }
5590bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson}
5600bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson
5610bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo HudsonSLuint32 AudioEngine::GetChannelCount() {
5620bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  android::Mutex::Autolock autoLock(callbackLock_);
5630bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  return mChannels;
5640bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson}
565b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
5660bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudsonstatic void CreateAndRealizeAudioPlayer(SLuint32 slSampleRate,
567dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda    size_t channelCount, SLuint32 slChannels, SLint32 audioStreamType, SLObjectItf &outputMix,
5680bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    SLObjectItf &audioPlayer, SLEngineItf &engineInterface) {
569b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // Define the source and sink for the audio player: comes from a buffer queue
570b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // and goes to the output mix.
571b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {
572b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2 };
5730bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM, channelCount, slSampleRate,
574b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
5750bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson      slChannels, SL_BYTEORDER_LITTLEENDIAN};
576b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  SLDataSource playingSrc = {&loc_bufq, &format_pcm};
577b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMix};
578b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  SLDataSink audioSnk = {&loc_outmix, NULL};
579b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
580b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // Create the audio player, which will play from the buffer queue and send to
581b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // the output mix.
582dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda  const size_t playerInterfaceCount = 2;
583b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  const SLInterfaceID iids[playerInterfaceCount] = {
584dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda      SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_ANDROIDCONFIGURATION };
585cd961432e31018599e107ef7bc008fd28d70b0c7Glenn Kasten  const SLboolean reqs[playerInterfaceCount] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
5860bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  OpenSL(engineInterface, CreateAudioPlayer, &audioPlayer, &playingSrc,
5870bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson      &audioSnk, playerInterfaceCount, iids, reqs);
588dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda  setAudioStreamType(audioPlayer, audioStreamType);
5890bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  OpenSL(audioPlayer, Realize, SL_BOOLEAN_FALSE);
5900bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson}
5910bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson
5920bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudsonbool AudioEngine::HasSampleRateAndChannels() {
5930bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  android::Mutex::Autolock autoLock(callbackLock_);
5940bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  return mChannels != 0 && mSampleRate != 0;
5959730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson}
5969730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
5979730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudsonbool AudioEngine::PlayFromThisSource(const SLDataSource& audioSrc) {
5989730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson  ClearDecodeBuffer();
5999730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
6009730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson  SLObjectItf engine;
6019730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson  SLEngineItf engineInterface;
6029730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson  CreateAndRealizeEngine(engine, engineInterface);
603b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
604b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // Define the source and sink for the decoding player: comes from the source
605b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // this method was called with, is sent to another buffer queue.
606b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  SLDataLocator_AndroidSimpleBufferQueue decBuffQueue;
607b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  decBuffQueue.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
608b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  decBuffQueue.numBuffers = kNumberOfBuffersInQueue;
609b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // A valid value seems required here but is currently ignored.
6109730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson  SLDataFormat_PCM pcm = {SL_DATAFORMAT_PCM, 1, SL_SAMPLINGRATE_44_1,
611b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      SL_PCMSAMPLEFORMAT_FIXED_16, 16,
612b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      SL_SPEAKER_FRONT_LEFT, SL_BYTEORDER_LITTLEENDIAN};
613b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  SLDataSink decDest = { &decBuffQueue, &pcm };
614b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
615b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // Create the decoder with the given source and sink.
616dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda  const size_t decoderInterfaceCount = 5;
617b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  SLObjectItf decoder;
618b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  const SLInterfaceID decodePlayerInterfaces[decoderInterfaceCount] = {
619b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_PREFETCHSTATUS, SL_IID_SEEK,
620dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda      SL_IID_METADATAEXTRACTION, SL_IID_ANDROIDCONFIGURATION };
621b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  const SLboolean decodePlayerRequired[decoderInterfaceCount] = {
622cd961432e31018599e107ef7bc008fd28d70b0c7Glenn Kasten      SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
623b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  SLDataSource sourceCopy(audioSrc);
6240bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  OpenSL(engineInterface, CreateAudioPlayer, &decoder, &sourceCopy, &decDest,
6250bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson      decoderInterfaceCount, decodePlayerInterfaces, decodePlayerRequired);
626dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda  // Not sure if this is necessary, but just in case.
627dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda  setAudioStreamType(decoder, audioStreamType_);
6280bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  OpenSL(decoder, Realize, SL_BOOLEAN_FALSE);
629b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
630b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // Get the play interface from the decoder, and register event callbacks.
631b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // Get the buffer queue, prefetch and seek interfaces.
6329730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson  SLPlayItf decoderPlay = NULL;
6330bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  SLAndroidSimpleBufferQueueItf decoderQueue = NULL;
6340bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  SLPrefetchStatusItf decoderPrefetch = NULL;
6350bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  SLSeekItf decoderSeek = NULL;
6360bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  SLMetadataExtractionItf decoderMetadata = NULL;
6370bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  OpenSL(decoder, GetInterface, SL_IID_PLAY, &decoderPlay);
6380bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  OpenSL(decoderPlay, SetCallbackEventsMask, SL_PLAYEVENT_HEADATEND);
6390bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  OpenSL(decoderPlay, RegisterCallback, DecodingEventCb, NULL);
6400bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  OpenSL(decoder, GetInterface, SL_IID_PREFETCHSTATUS, &decoderPrefetch);
6410bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  OpenSL(decoder, GetInterface, SL_IID_SEEK, &decoderSeek);
6420bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  OpenSL(decoder, GetInterface, SL_IID_METADATAEXTRACTION, &decoderMetadata);
6430bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  OpenSL(decoder, GetInterface, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
6440bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson      &decoderQueue);
6459730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
6460bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  // Initialize the callback structure, used during the decoding.
6479730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson  CallbackContext callbackContext;
6480bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  {
6490bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    android::Mutex::Autolock autoLock(callbackLock_);
6500bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    callbackContext.pDataBase = pcmData;
6510bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    callbackContext.pData = pcmData;
6520bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    callbackContext.decoderMetadata = decoderMetadata;
6530bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    callbackContext.playItf = decoderPlay;
6540bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    RegisterCallbackContextAndAddEnqueueBuffersToDecoder(
6550bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson        decoderQueue, &callbackContext);
6560bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  }
657b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
658b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // Initialize the callback for prefetch errors, if we can't open the
659b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // resource to decode.
6600bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  OpenSL(decoderPrefetch, SetCallbackEventsMask, kPrefetchErrorCandidate);
6610bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  OpenSL(decoderPrefetch, RegisterCallback, PrefetchEventCb, &decoderPrefetch);
662b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
6630bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  // Seek to the start position.
6640bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  OpenSL(decoderSeek, SetPosition, startPositionMillis_, SL_SEEKMODE_ACCURATE);
665b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
6660bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  // Start decoding immediately.
6670bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  OpenSL(decoderPlay, SetPlayState, SL_PLAYSTATE_PLAYING);
668b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
6690bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  // These variables hold the audio player and its output.
6700bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  // They will only be constructed once the decoder has invoked the callback,
6710bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  // and given us the correct sample rate, number of channels and duration.
6729730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson  SLObjectItf outputMix = NULL;
6739730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson  SLObjectItf audioPlayer = NULL;
6749730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson  SLPlayItf audioPlayerPlay = NULL;
6759730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson  SLAndroidSimpleBufferQueueItf audioPlayerQueue = NULL;
6769730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
677b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // The main loop - until we're told to stop: if there is audio data coming
678b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // out of the decoder, feed it through the time scaler.
679b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // As it comes out of the time scaler, feed it into the audio player.
680b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  while (!Finished()) {
6810bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    if (GetWasStartRequested() && HasSampleRateAndChannels()) {
6820bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson      // Build the audio player.
6830bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson      // TODO: What happens if I maliciously call start lots of times?
6840bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson      floatBuffer_ = new float[targetFrames_ * mChannels];
6850bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson      injectBuffer_ = new float[targetFrames_ * mChannels];
6860bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson      OpenSL(engineInterface, CreateOutputMix, &outputMix, 0, NULL, NULL);
6870bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson      OpenSL(outputMix, Realize, SL_BOOLEAN_FALSE);
6880bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson      CreateAndRealizeAudioPlayer(GetSLSampleRate(), GetChannelCount(),
689dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda          GetSLChannels(), audioStreamType_, outputMix, audioPlayer,
690dc442b4d99512bf7c41ee5ceae6c93a3c3568b57Flavio Lerda          engineInterface);
6910bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson      OpenSL(audioPlayer, GetInterface, SL_IID_PLAY, &audioPlayerPlay);
6920bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson      OpenSL(audioPlayer, GetInterface, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
6930bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson          &audioPlayerQueue);
6940bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson      OpenSL(audioPlayerQueue, RegisterCallback, PlayingBufferQueueCb, NULL);
695b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      ClearRequestStart();
6960bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson      OpenSL(audioPlayerPlay, SetPlayState, SL_PLAYSTATE_PLAYING);
697b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    }
698b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    EnqueueMoreAudioIfNecessary(audioPlayerQueue);
699b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    usleep(kSleepTimeMicros);
700b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  }
701b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
7029730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson  // Delete the audio player and output mix, iff they have been created.
7039730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson  if (audioPlayer != NULL) {
7040bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    OpenSL(audioPlayerPlay, SetPlayState, SL_PLAYSTATE_STOPPED);
7050bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    OpenSL0(audioPlayerQueue, Clear);
7060bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    OpenSL(audioPlayerQueue, RegisterCallback, NULL, NULL);
7070bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    VoidOpenSL(audioPlayer, AbortAsyncOperation);
7080bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    VoidOpenSL(audioPlayer, Destroy);
7090bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    VoidOpenSL(outputMix, Destroy);
7109730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    audioPlayer = NULL;
7119730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    audioPlayerPlay = NULL;
7129730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    audioPlayerQueue = NULL;
7139730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson    outputMix = NULL;
7149730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson  }
715b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
716b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // Delete the decoder.
7170bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  OpenSL(decoderPlay, SetPlayState, SL_PLAYSTATE_STOPPED);
7180bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  OpenSL(decoderPrefetch, RegisterCallback, NULL, NULL);
7199730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson  // This is returning slresult 13 if I do no playback.
720b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // Repro is to comment out all before this line, and all after enqueueing
721b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // my buffers.
7220bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  // OpenSL0(decoderQueue, Clear);
7230bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  OpenSL(decoderQueue, RegisterCallback, NULL, NULL);
724b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  decoderSeek = NULL;
725b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  decoderPrefetch = NULL;
726b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  decoderQueue = NULL;
7270bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  OpenSL(decoderPlay, RegisterCallback, NULL, NULL);
7280bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  VoidOpenSL(decoder, AbortAsyncOperation);
7290bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  VoidOpenSL(decoder, Destroy);
730b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  decoderPlay = NULL;
731b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
7329730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson  // Delete the engine.
7330bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  VoidOpenSL(engine, Destroy);
7349730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson  engineInterface = NULL;
735b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
736b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  return true;
737b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
738b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
739b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonbool AudioEngine::Finished() {
740b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  if (GetWasStopRequested()) {
741b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    return true;
742b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  }
743b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  android::Mutex::Autolock autoLock(playBufferLock_);
744b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  return playingBuffers_.size() <= 0 &&
745b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      IsDecodeBufferEmpty() &&
746b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      GetEndOfDecoderReached();
747b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
748b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
749b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonbool AudioEngine::GetWasStopRequested() {
750b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  android::Mutex::Autolock autoLock(lock_);
751b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  return stopRequested_;
752b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
753b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
754b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonbool AudioEngine::GetHasReachedPlayingBuffersLimit() {
755b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  android::Mutex::Autolock autoLock(playBufferLock_);
756b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  return playingBuffers_.size() >= maxPlayBufferCount_;
757b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
758b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
759b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonvoid AudioEngine::EnqueueMoreAudioIfNecessary(
760b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    SLAndroidSimpleBufferQueueItf audioPlayerQueue) {
761b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  bool keepEnqueueing = true;
7620bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  while (audioPlayerQueue != NULL &&
7630bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson         !GetWasStopRequested() &&
764b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson         !IsDecodeBufferEmpty() &&
765b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson         !GetHasReachedPlayingBuffersLimit() &&
766b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson         keepEnqueueing) {
767b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    keepEnqueueing = EnqueueNextBufferOfAudio(audioPlayerQueue);
768b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  }
769b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
770b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
771b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonbool AudioEngine::DecodeBufferTooFull() {
772b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  android::Mutex::Autolock autoLock(decodeBufferLock_);
773b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  return decodeBuffer_.IsTooLarge();
774b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
775b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
776b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// ****************************************************************************
777b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson// Code for handling the static callbacks.
778b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
779b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonvoid AudioEngine::PlayingBufferQueueCallback() {
780b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // The head playing buffer is done, move it to the free list.
781b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  android::Mutex::Autolock autoLock(playBufferLock_);
782b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  if (playingBuffers_.size() > 0) {
783b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    freeBuffers_.push(playingBuffers_.front());
784b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    playingBuffers_.pop();
785b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  }
786b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
787b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
788b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonvoid AudioEngine::PrefetchEventCallback(
789b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    SLPrefetchStatusItf caller, SLuint32 event) {
790b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // If there was a problem during decoding, then signal the end.
791b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  SLpermille level = 0;
792b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  SLuint32 status;
7930bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  OpenSL(caller, GetFillLevel, &level);
7940bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  OpenSL(caller, GetPrefetchStatus, &status);
795b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  if ((kPrefetchErrorCandidate == (event & kPrefetchErrorCandidate)) &&
796b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      (level == 0) &&
797b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      (status == SL_PREFETCHSTATUS_UNDERFLOW)) {
7980bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    LOGI("prefetcheventcallback error while prefetching data");
799b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    SetEndOfDecoderReached();
800b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  }
801b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  if (SL_PREFETCHSTATUS_SUFFICIENTDATA == event) {
802b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    // android::Mutex::Autolock autoLock(prefetchLock_);
803b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    // prefetchCondition_.broadcast();
804b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  }
805b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
806b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
807b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonvoid AudioEngine::DecodingBufferQueueCallback(
808b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    SLAndroidSimpleBufferQueueItf queueItf, void *context) {
809b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  if (GetWasStopRequested()) {
810b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    return;
811b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  }
812b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
813b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  CallbackContext *pCntxt;
814b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  {
815b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    android::Mutex::Autolock autoLock(callbackLock_);
816b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    pCntxt = reinterpret_cast<CallbackContext*>(context);
817b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  }
818b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  {
819b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    android::Mutex::Autolock autoLock(decodeBufferLock_);
820d2772c48b3ba3cb78f814f83f4a65bbac2cf8337Hugo Hudson    decodeBuffer_.AddData(pCntxt->pData, kBufferSizeInBytes);
821b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  }
822b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
8230bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  if (!HasSampleRateAndChannels()) {
8240bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    android::Mutex::Autolock autoLock(callbackLock_);
8250bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    ReadSampleRateAndChannelCount(pCntxt, &mSampleRate, &mChannels);
8260bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  }
8270bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson
8280bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  {
8290bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    android::Mutex::Autolock autoLock(lock_);
8300bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    if (totalDurationMs_ == 0) {
8310bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson      totalDurationMs_ = ReadDuration(pCntxt->playItf);
8320bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    }
8330bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    // TODO: This isn't working, it always reports zero.
8340bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson    // ReadPosition(pCntxt->playItf);
8350bd6ec5bc06b869131ee0facf38ff02f81f65c10Hugo Hudson  }
8369730f15ebbf4b64cd48e0777850e56cb516a9ed4Hugo Hudson
837d2772c48b3ba3cb78f814f83f4a65bbac2cf8337Hugo Hudson  OpenSL(queueItf, Enqueue, pCntxt->pData, kBufferSizeInBytes);
838d2772c48b3ba3cb78f814f83f4a65bbac2cf8337Hugo Hudson
839b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // Increase data pointer by buffer size
840b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  pCntxt->pData += kBufferSizeInBytes;
841b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  if (pCntxt->pData >= pCntxt->pDataBase +
842b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson      (kNumberOfBuffersInQueue * kBufferSizeInBytes)) {
843b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    pCntxt->pData = pCntxt->pDataBase;
844b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  }
845b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
846b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // If we get too much data into the decoder,
847b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  // sleep until the playback catches up.
848b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  while (!GetWasStopRequested() && DecodeBufferTooFull()) {
849b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    usleep(kSleepTimeMicros);
850b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  }
851b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
852b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson
853b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudsonvoid AudioEngine::DecodingEventCallback(SLPlayItf, SLuint32 event) {
854b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  if (SL_PLAYEVENT_HEADATEND & event) {
855b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson    SetEndOfDecoderReached();
856b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson  }
857b83ad73794088498d6d38cd3b4fc9311f505d051Hugo Hudson}
858