1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "BufferProvider"
18 //#define LOG_NDEBUG 0
19 
20 #include <algorithm>
21 
22 #include <audio_utils/primitives.h>
23 #include <audio_utils/format.h>
24 #include <audio_utils/channels.h>
25 #include <sonic.h>
26 #include <media/audiohal/EffectBufferHalInterface.h>
27 #include <media/audiohal/EffectHalInterface.h>
28 #include <media/audiohal/EffectsFactoryHalInterface.h>
29 #include <media/AudioResamplerPublic.h>
30 #include <media/BufferProviders.h>
31 #include <system/audio_effects/effect_downmix.h>
32 #include <utils/Log.h>
33 
34 #ifndef ARRAY_SIZE
35 #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
36 #endif
37 
38 namespace android {
39 
40 // ----------------------------------------------------------------------------
CopyBufferProvider(size_t inputFrameSize,size_t outputFrameSize,size_t bufferFrameCount)41 CopyBufferProvider::CopyBufferProvider(size_t inputFrameSize,
42         size_t outputFrameSize, size_t bufferFrameCount) :
43         mInputFrameSize(inputFrameSize),
44         mOutputFrameSize(outputFrameSize),
45         mLocalBufferFrameCount(bufferFrameCount),
46         mLocalBufferData(NULL),
47         mConsumed(0)
48 {
49     ALOGV("CopyBufferProvider(%p)(%zu, %zu, %zu)", this,
50             inputFrameSize, outputFrameSize, bufferFrameCount);
51     LOG_ALWAYS_FATAL_IF(inputFrameSize < outputFrameSize && bufferFrameCount == 0,
52             "Requires local buffer if inputFrameSize(%zu) < outputFrameSize(%zu)",
53             inputFrameSize, outputFrameSize);
54     if (mLocalBufferFrameCount) {
55         (void)posix_memalign(&mLocalBufferData, 32, mLocalBufferFrameCount * mOutputFrameSize);
56     }
57     mBuffer.frameCount = 0;
58 }
59 
~CopyBufferProvider()60 CopyBufferProvider::~CopyBufferProvider()
61 {
62     ALOGV("%s(%p) %zu %p %p",
63            __func__, this, mBuffer.frameCount, mTrackBufferProvider, mLocalBufferData);
64     if (mBuffer.frameCount != 0) {
65         mTrackBufferProvider->releaseBuffer(&mBuffer);
66     }
67     free(mLocalBufferData);
68 }
69 
getNextBuffer(AudioBufferProvider::Buffer * pBuffer)70 status_t CopyBufferProvider::getNextBuffer(AudioBufferProvider::Buffer *pBuffer)
71 {
72     //ALOGV("CopyBufferProvider(%p)::getNextBuffer(%p (%zu))",
73     //        this, pBuffer, pBuffer->frameCount);
74     if (mLocalBufferFrameCount == 0) {
75         status_t res = mTrackBufferProvider->getNextBuffer(pBuffer);
76         if (res == OK) {
77             copyFrames(pBuffer->raw, pBuffer->raw, pBuffer->frameCount);
78         }
79         return res;
80     }
81     if (mBuffer.frameCount == 0) {
82         mBuffer.frameCount = pBuffer->frameCount;
83         status_t res = mTrackBufferProvider->getNextBuffer(&mBuffer);
84         // At one time an upstream buffer provider had
85         // res == OK and mBuffer.frameCount == 0, doesn't seem to happen now 7/18/2014.
86         //
87         // By API spec, if res != OK, then mBuffer.frameCount == 0.
88         // but there may be improper implementations.
89         ALOG_ASSERT(res == OK || mBuffer.frameCount == 0);
90         if (res != OK || mBuffer.frameCount == 0) { // not needed by API spec, but to be safe.
91             pBuffer->raw = NULL;
92             pBuffer->frameCount = 0;
93             return res;
94         }
95         mConsumed = 0;
96     }
97     ALOG_ASSERT(mConsumed < mBuffer.frameCount);
98     size_t count = std::min(mLocalBufferFrameCount, mBuffer.frameCount - mConsumed);
99     count = std::min(count, pBuffer->frameCount);
100     pBuffer->raw = mLocalBufferData;
101     pBuffer->frameCount = count;
102     copyFrames(pBuffer->raw, (uint8_t*)mBuffer.raw + mConsumed * mInputFrameSize,
103             pBuffer->frameCount);
104     return OK;
105 }
106 
releaseBuffer(AudioBufferProvider::Buffer * pBuffer)107 void CopyBufferProvider::releaseBuffer(AudioBufferProvider::Buffer *pBuffer)
108 {
109     //ALOGV("CopyBufferProvider(%p)::releaseBuffer(%p(%zu))",
110     //        this, pBuffer, pBuffer->frameCount);
111     if (mLocalBufferFrameCount == 0) {
112         mTrackBufferProvider->releaseBuffer(pBuffer);
113         return;
114     }
115     // LOG_ALWAYS_FATAL_IF(pBuffer->frameCount == 0, "Invalid framecount");
116     mConsumed += pBuffer->frameCount; // TODO: update for efficiency to reuse existing content
117     if (mConsumed != 0 && mConsumed >= mBuffer.frameCount) {
118         mTrackBufferProvider->releaseBuffer(&mBuffer);
119         ALOG_ASSERT(mBuffer.frameCount == 0);
120     }
121     pBuffer->raw = NULL;
122     pBuffer->frameCount = 0;
123 }
124 
reset()125 void CopyBufferProvider::reset()
126 {
127     if (mBuffer.frameCount != 0) {
128         mTrackBufferProvider->releaseBuffer(&mBuffer);
129     }
130     mConsumed = 0;
131 }
132 
setBufferProvider(AudioBufferProvider * p)133 void CopyBufferProvider::setBufferProvider(AudioBufferProvider *p) {
134     ALOGV("%s(%p): mTrackBufferProvider:%p  mBuffer.frameCount:%zu",
135             __func__, p, mTrackBufferProvider, mBuffer.frameCount);
136     if (mTrackBufferProvider == p) {
137         return;
138     }
139     mBuffer.frameCount = 0;
140     PassthruBufferProvider::setBufferProvider(p);
141 }
142 
DownmixerBufferProvider(audio_channel_mask_t inputChannelMask,audio_channel_mask_t outputChannelMask,audio_format_t format,uint32_t sampleRate,int32_t sessionId,size_t bufferFrameCount)143 DownmixerBufferProvider::DownmixerBufferProvider(
144         audio_channel_mask_t inputChannelMask,
145         audio_channel_mask_t outputChannelMask, audio_format_t format,
146         uint32_t sampleRate, int32_t sessionId, size_t bufferFrameCount) :
147         CopyBufferProvider(
148             audio_bytes_per_sample(format) * audio_channel_count_from_out_mask(inputChannelMask),
149             audio_bytes_per_sample(format) * audio_channel_count_from_out_mask(outputChannelMask),
150             bufferFrameCount)  // set bufferFrameCount to 0 to do in-place
151 {
152     ALOGV("DownmixerBufferProvider(%p)(%#x, %#x, %#x %u %d %d)",
153             this, inputChannelMask, outputChannelMask, format,
154             sampleRate, sessionId, (int)bufferFrameCount);
155     if (!sIsMultichannelCapable) {
156         ALOGE("DownmixerBufferProvider() error: not multichannel capable");
157         return;
158     }
159     mEffectsFactory = EffectsFactoryHalInterface::create();
160     if (mEffectsFactory == 0) {
161         ALOGE("DownmixerBufferProvider() error: could not obtain the effects factory");
162         return;
163     }
164     if (mEffectsFactory->createEffect(&sDwnmFxDesc.uuid,
165                                       sessionId,
166                                       SESSION_ID_INVALID_AND_IGNORED,
167                                       AUDIO_PORT_HANDLE_NONE,
168                                       &mDownmixInterface) != 0) {
169          ALOGE("DownmixerBufferProvider() error creating downmixer effect");
170          mDownmixInterface.clear();
171          mEffectsFactory.clear();
172          return;
173      }
174      // channel input configuration will be overridden per-track
175      mDownmixConfig.inputCfg.channels = inputChannelMask;   // FIXME: Should be bits
176      mDownmixConfig.outputCfg.channels = outputChannelMask; // FIXME: should be bits
177      mDownmixConfig.inputCfg.format = format;
178      mDownmixConfig.outputCfg.format = format;
179      mDownmixConfig.inputCfg.samplingRate = sampleRate;
180      mDownmixConfig.outputCfg.samplingRate = sampleRate;
181      mDownmixConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
182      mDownmixConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_WRITE;
183      // input and output buffer provider, and frame count will not be used as the downmix effect
184      // process() function is called directly (see DownmixerBufferProvider::getNextBuffer())
185      mDownmixConfig.inputCfg.mask = EFFECT_CONFIG_SMP_RATE | EFFECT_CONFIG_CHANNELS |
186              EFFECT_CONFIG_FORMAT | EFFECT_CONFIG_ACC_MODE;
187      mDownmixConfig.outputCfg.mask = mDownmixConfig.inputCfg.mask;
188      mDownmixConfig.inputCfg.buffer.frameCount = bufferFrameCount;
189      mDownmixConfig.outputCfg.buffer.frameCount = bufferFrameCount;
190 
191      mInFrameSize =
192              audio_bytes_per_sample(format) * audio_channel_count_from_out_mask(inputChannelMask);
193      mOutFrameSize =
194              audio_bytes_per_sample(format) * audio_channel_count_from_out_mask(outputChannelMask);
195      status_t status;
196      status = mEffectsFactory->mirrorBuffer(
197              nullptr, mInFrameSize * bufferFrameCount, &mInBuffer);
198      if (status != 0) {
199          ALOGE("DownmixerBufferProvider() error %d while creating input buffer", status);
200          mDownmixInterface.clear();
201          mEffectsFactory.clear();
202          return;
203      }
204      status = mEffectsFactory->mirrorBuffer(
205              nullptr, mOutFrameSize * bufferFrameCount, &mOutBuffer);
206      if (status != 0) {
207          ALOGE("DownmixerBufferProvider() error %d while creating output buffer", status);
208          mInBuffer.clear();
209          mDownmixInterface.clear();
210          mEffectsFactory.clear();
211          return;
212      }
213      mDownmixInterface->setInBuffer(mInBuffer);
214      mDownmixInterface->setOutBuffer(mOutBuffer);
215 
216      int cmdStatus;
217      uint32_t replySize = sizeof(int);
218 
219      // Configure downmixer
220      status = mDownmixInterface->command(
221              EFFECT_CMD_SET_CONFIG /*cmdCode*/, sizeof(effect_config_t) /*cmdSize*/,
222              &mDownmixConfig /*pCmdData*/,
223              &replySize, &cmdStatus /*pReplyData*/);
224      if (status != 0 || cmdStatus != 0) {
225          ALOGE("DownmixerBufferProvider() error %d cmdStatus %d while configuring downmixer",
226                  status, cmdStatus);
227          mOutBuffer.clear();
228          mInBuffer.clear();
229          mDownmixInterface.clear();
230          mEffectsFactory.clear();
231          return;
232      }
233 
234      // Enable downmixer
235      replySize = sizeof(int);
236      status = mDownmixInterface->command(
237              EFFECT_CMD_ENABLE /*cmdCode*/, 0 /*cmdSize*/, NULL /*pCmdData*/,
238              &replySize, &cmdStatus /*pReplyData*/);
239      if (status != 0 || cmdStatus != 0) {
240          ALOGE("DownmixerBufferProvider() error %d cmdStatus %d while enabling downmixer",
241                  status, cmdStatus);
242          mOutBuffer.clear();
243          mInBuffer.clear();
244          mDownmixInterface.clear();
245          mEffectsFactory.clear();
246          return;
247      }
248 
249      // Set downmix type
250      // parameter size rounded for padding on 32bit boundary
251      const int psizePadded = ((sizeof(downmix_params_t) - 1)/sizeof(int) + 1) * sizeof(int);
252      const int downmixParamSize =
253              sizeof(effect_param_t) + psizePadded + sizeof(downmix_type_t);
254      effect_param_t * const param = (effect_param_t *) malloc(downmixParamSize);
255      param->psize = sizeof(downmix_params_t);
256      const downmix_params_t downmixParam = DOWNMIX_PARAM_TYPE;
257      memcpy(param->data, &downmixParam, param->psize);
258      const downmix_type_t downmixType = DOWNMIX_TYPE_FOLD;
259      param->vsize = sizeof(downmix_type_t);
260      memcpy(param->data + psizePadded, &downmixType, param->vsize);
261      replySize = sizeof(int);
262      status = mDownmixInterface->command(
263              EFFECT_CMD_SET_PARAM /* cmdCode */, downmixParamSize /* cmdSize */,
264              param /*pCmdData*/, &replySize, &cmdStatus /*pReplyData*/);
265      free(param);
266      if (status != 0 || cmdStatus != 0) {
267          ALOGE("DownmixerBufferProvider() error %d cmdStatus %d while setting downmix type",
268                  status, cmdStatus);
269          mOutBuffer.clear();
270          mInBuffer.clear();
271          mDownmixInterface.clear();
272          mEffectsFactory.clear();
273          return;
274      }
275      ALOGV("DownmixerBufferProvider() downmix type set to %d", (int) downmixType);
276 }
277 
~DownmixerBufferProvider()278 DownmixerBufferProvider::~DownmixerBufferProvider()
279 {
280     ALOGV("~DownmixerBufferProvider (%p)", this);
281     if (mDownmixInterface != 0) {
282         mDownmixInterface->close();
283     }
284 }
285 
copyFrames(void * dst,const void * src,size_t frames)286 void DownmixerBufferProvider::copyFrames(void *dst, const void *src, size_t frames)
287 {
288     mInBuffer->setExternalData(const_cast<void*>(src));
289     mInBuffer->setFrameCount(frames);
290     mInBuffer->update(mInFrameSize * frames);
291     mOutBuffer->setFrameCount(frames);
292     mOutBuffer->setExternalData(dst);
293     if (dst != src) {
294         // Downmix may be accumulating, need to populate the output buffer
295         // with the dst data.
296         mOutBuffer->update(mOutFrameSize * frames);
297     }
298     // may be in-place if src == dst.
299     status_t res = mDownmixInterface->process();
300     if (res == OK) {
301         mOutBuffer->commit(mOutFrameSize * frames);
302     } else {
303         ALOGE("DownmixBufferProvider error %d", res);
304     }
305 }
306 
307 /* call once in a pthread_once handler. */
init()308 /*static*/ status_t DownmixerBufferProvider::init()
309 {
310     // find multichannel downmix effect if we have to play multichannel content
311     sp<EffectsFactoryHalInterface> effectsFactory = EffectsFactoryHalInterface::create();
312     if (effectsFactory == 0) {
313         ALOGE("AudioMixer() error: could not obtain the effects factory");
314         return NO_INIT;
315     }
316     uint32_t numEffects = 0;
317     int ret = effectsFactory->queryNumberEffects(&numEffects);
318     if (ret != 0) {
319         ALOGE("AudioMixer() error %d querying number of effects", ret);
320         return NO_INIT;
321     }
322     ALOGV("EffectQueryNumberEffects() numEffects=%d", numEffects);
323 
324     for (uint32_t i = 0 ; i < numEffects ; i++) {
325         if (effectsFactory->getDescriptor(i, &sDwnmFxDesc) == 0) {
326             ALOGV("effect %d is called %s", i, sDwnmFxDesc.name);
327             if (memcmp(&sDwnmFxDesc.type, EFFECT_UIID_DOWNMIX, sizeof(effect_uuid_t)) == 0) {
328                 ALOGI("found effect \"%s\" from %s",
329                         sDwnmFxDesc.name, sDwnmFxDesc.implementor);
330                 sIsMultichannelCapable = true;
331                 break;
332             }
333         }
334     }
335     ALOGW_IF(!sIsMultichannelCapable, "unable to find downmix effect");
336     return NO_INIT;
337 }
338 
339 /*static*/ bool DownmixerBufferProvider::sIsMultichannelCapable = false;
340 /*static*/ effect_descriptor_t DownmixerBufferProvider::sDwnmFxDesc;
341 
RemixBufferProvider(audio_channel_mask_t inputChannelMask,audio_channel_mask_t outputChannelMask,audio_format_t format,size_t bufferFrameCount)342 RemixBufferProvider::RemixBufferProvider(audio_channel_mask_t inputChannelMask,
343         audio_channel_mask_t outputChannelMask, audio_format_t format,
344         size_t bufferFrameCount) :
345         CopyBufferProvider(
346                 audio_bytes_per_sample(format)
347                     * audio_channel_count_from_out_mask(inputChannelMask),
348                 audio_bytes_per_sample(format)
349                     * audio_channel_count_from_out_mask(outputChannelMask),
350                 bufferFrameCount),
351         mFormat(format),
352         mSampleSize(audio_bytes_per_sample(format)),
353         mInputChannels(audio_channel_count_from_out_mask(inputChannelMask)),
354         mOutputChannels(audio_channel_count_from_out_mask(outputChannelMask))
355 {
356     ALOGV("RemixBufferProvider(%p)(%#x, %#x, %#x) %zu %zu",
357             this, format, inputChannelMask, outputChannelMask,
358             mInputChannels, mOutputChannels);
359     (void) memcpy_by_index_array_initialization_from_channel_mask(
360             mIdxAry, ARRAY_SIZE(mIdxAry), outputChannelMask, inputChannelMask);
361 }
362 
copyFrames(void * dst,const void * src,size_t frames)363 void RemixBufferProvider::copyFrames(void *dst, const void *src, size_t frames)
364 {
365     memcpy_by_index_array(dst, mOutputChannels,
366             src, mInputChannels, mIdxAry, mSampleSize, frames);
367 }
368 
ChannelMixBufferProvider(audio_channel_mask_t inputChannelMask,audio_channel_mask_t outputChannelMask,audio_format_t format,size_t bufferFrameCount)369 ChannelMixBufferProvider::ChannelMixBufferProvider(audio_channel_mask_t inputChannelMask,
370         audio_channel_mask_t outputChannelMask, audio_format_t format,
371         size_t bufferFrameCount) :
372         CopyBufferProvider(
373                 audio_bytes_per_sample(format)
374                     * audio_channel_count_from_out_mask(inputChannelMask),
375                 audio_bytes_per_sample(format)
376                     * audio_channel_count_from_out_mask(outputChannelMask),
377                 bufferFrameCount)
378         , mChannelMix{format == AUDIO_FORMAT_PCM_FLOAT
379                 ? audio_utils::channels::IChannelMix::create(outputChannelMask) : nullptr}
380         , mIsValid{mChannelMix && mChannelMix->setInputChannelMask(inputChannelMask)}
381 {
382     ALOGV("ChannelMixBufferProvider(%p)(%#x, %#x, %#x)",
383             this, format, inputChannelMask, outputChannelMask);
384 }
385 
copyFrames(void * dst,const void * src,size_t frames)386 void ChannelMixBufferProvider::copyFrames(void *dst, const void *src, size_t frames)
387 {
388     if (mIsValid) {
389         mChannelMix->process(static_cast<const float *>(src), static_cast<float *>(dst),
390                 frames, false /* accumulate */);
391     } else {
392         // Should fall back to a different BufferProvider if not valid.
393         ALOGE("%s: Use without being valid!", __func__);
394     }
395 }
396 
ReformatBufferProvider(int32_t channelCount,audio_format_t inputFormat,audio_format_t outputFormat,size_t bufferFrameCount)397 ReformatBufferProvider::ReformatBufferProvider(int32_t channelCount,
398         audio_format_t inputFormat, audio_format_t outputFormat,
399         size_t bufferFrameCount) :
400         CopyBufferProvider(
401                 channelCount * audio_bytes_per_sample(inputFormat),
402                 channelCount * audio_bytes_per_sample(outputFormat),
403                 bufferFrameCount),
404         mChannelCount(channelCount),
405         mInputFormat(inputFormat),
406         mOutputFormat(outputFormat)
407 {
408     ALOGV("ReformatBufferProvider(%p)(%u, %#x, %#x)",
409             this, channelCount, inputFormat, outputFormat);
410 }
411 
copyFrames(void * dst,const void * src,size_t frames)412 void ReformatBufferProvider::copyFrames(void *dst, const void *src, size_t frames)
413 {
414     memcpy_by_audio_format(dst, mOutputFormat, src, mInputFormat, frames * mChannelCount);
415 }
416 
ClampFloatBufferProvider(int32_t channelCount,size_t bufferFrameCount)417 ClampFloatBufferProvider::ClampFloatBufferProvider(int32_t channelCount, size_t bufferFrameCount) :
418         CopyBufferProvider(
419                 channelCount * audio_bytes_per_sample(AUDIO_FORMAT_PCM_FLOAT),
420                 channelCount * audio_bytes_per_sample(AUDIO_FORMAT_PCM_FLOAT),
421                 bufferFrameCount),
422         mChannelCount(channelCount)
423 {
424     ALOGV("ClampFloatBufferProvider(%p)(%u)", this, channelCount);
425 }
426 
copyFrames(void * dst,const void * src,size_t frames)427 void ClampFloatBufferProvider::copyFrames(void *dst, const void *src, size_t frames)
428 {
429     memcpy_to_float_from_float_with_clamping((float*)dst, (const float*)src,
430                                              frames * mChannelCount,
431                                              FLOAT_NOMINAL_RANGE_HEADROOM);
432 }
433 
TimestretchBufferProvider(int32_t channelCount,audio_format_t format,uint32_t sampleRate,const AudioPlaybackRate & playbackRate)434 TimestretchBufferProvider::TimestretchBufferProvider(int32_t channelCount,
435         audio_format_t format, uint32_t sampleRate, const AudioPlaybackRate &playbackRate) :
436         mChannelCount(channelCount),
437         mFormat(format),
438         mSampleRate(sampleRate),
439         mFrameSize(channelCount * audio_bytes_per_sample(format)),
440         mLocalBufferFrameCount(0),
441         mLocalBufferData(NULL),
442         mRemaining(0),
443         mSonicStream(sonicCreateStream(sampleRate, mChannelCount)),
444         mFallbackFailErrorShown(false),
445         mAudioPlaybackRateValid(false)
446 {
447     LOG_ALWAYS_FATAL_IF(mSonicStream == NULL,
448             "TimestretchBufferProvider can't allocate Sonic stream");
449 
450     setPlaybackRate(playbackRate);
451     ALOGV("TimestretchBufferProvider(%p)(%u, %#x, %u %f %f %d %d)",
452             this, channelCount, format, sampleRate, playbackRate.mSpeed,
453             playbackRate.mPitch, playbackRate.mStretchMode, playbackRate.mFallbackMode);
454     mBuffer.frameCount = 0;
455 }
456 
~TimestretchBufferProvider()457 TimestretchBufferProvider::~TimestretchBufferProvider()
458 {
459     ALOGV("~TimestretchBufferProvider(%p)", this);
460     sonicDestroyStream(mSonicStream);
461     if (mBuffer.frameCount != 0) {
462         mTrackBufferProvider->releaseBuffer(&mBuffer);
463     }
464     free(mLocalBufferData);
465 }
466 
getNextBuffer(AudioBufferProvider::Buffer * pBuffer)467 status_t TimestretchBufferProvider::getNextBuffer(
468         AudioBufferProvider::Buffer *pBuffer)
469 {
470     ALOGV("TimestretchBufferProvider(%p)::getNextBuffer(%p (%zu))",
471             this, pBuffer, pBuffer->frameCount);
472 
473     // BYPASS
474     //return mTrackBufferProvider->getNextBuffer(pBuffer);
475 
476     // check if previously processed data is sufficient.
477     if (pBuffer->frameCount <= mRemaining) {
478         ALOGV("previous sufficient");
479         pBuffer->raw = mLocalBufferData;
480         return OK;
481     }
482 
483     // do we need to resize our buffer?
484     if (pBuffer->frameCount > mLocalBufferFrameCount) {
485         void *newmem;
486         if (posix_memalign(&newmem, 32, pBuffer->frameCount * mFrameSize) == OK) {
487             if (mRemaining != 0) {
488                 memcpy(newmem, mLocalBufferData, mRemaining * mFrameSize);
489             }
490             free(mLocalBufferData);
491             mLocalBufferData = newmem;
492             mLocalBufferFrameCount = pBuffer->frameCount;
493         }
494     }
495 
496     // need to fetch more data
497     const size_t outputDesired = pBuffer->frameCount - mRemaining;
498     size_t dstAvailable;
499     do {
500         mBuffer.frameCount = mPlaybackRate.mSpeed == AUDIO_TIMESTRETCH_SPEED_NORMAL
501                 ? outputDesired : outputDesired * mPlaybackRate.mSpeed + 1;
502 
503         status_t res = mTrackBufferProvider->getNextBuffer(&mBuffer);
504 
505         ALOG_ASSERT(res == OK || mBuffer.frameCount == 0);
506         if (res != OK || mBuffer.frameCount == 0) { // not needed by API spec, but to be safe.
507             ALOGV("upstream provider cannot provide data");
508             if (mRemaining == 0) {
509                 pBuffer->raw = NULL;
510                 pBuffer->frameCount = 0;
511                 return res;
512             } else { // return partial count
513                 pBuffer->raw = mLocalBufferData;
514                 pBuffer->frameCount = mRemaining;
515                 return OK;
516             }
517         }
518 
519         // time-stretch the data
520         dstAvailable = std::min(mLocalBufferFrameCount - mRemaining, outputDesired);
521         size_t srcAvailable = mBuffer.frameCount;
522         processFrames((uint8_t*)mLocalBufferData + mRemaining * mFrameSize, &dstAvailable,
523                 mBuffer.raw, &srcAvailable);
524 
525         // release all data consumed
526         mBuffer.frameCount = srcAvailable;
527         mTrackBufferProvider->releaseBuffer(&mBuffer);
528     } while (dstAvailable == 0); // try until we get output data or upstream provider fails.
529 
530     // update buffer vars with the actual data processed and return with buffer
531     mRemaining += dstAvailable;
532 
533     pBuffer->raw = mLocalBufferData;
534     pBuffer->frameCount = mRemaining;
535 
536     return OK;
537 }
538 
releaseBuffer(AudioBufferProvider::Buffer * pBuffer)539 void TimestretchBufferProvider::releaseBuffer(AudioBufferProvider::Buffer *pBuffer)
540 {
541     ALOGV("TimestretchBufferProvider(%p)::releaseBuffer(%p (%zu))",
542        this, pBuffer, pBuffer->frameCount);
543 
544     // BYPASS
545     //return mTrackBufferProvider->releaseBuffer(pBuffer);
546 
547     // LOG_ALWAYS_FATAL_IF(pBuffer->frameCount == 0, "Invalid framecount");
548     if (pBuffer->frameCount < mRemaining) {
549         memcpy(mLocalBufferData,
550                 (uint8_t*)mLocalBufferData + pBuffer->frameCount * mFrameSize,
551                 (mRemaining - pBuffer->frameCount) * mFrameSize);
552         mRemaining -= pBuffer->frameCount;
553     } else if (pBuffer->frameCount == mRemaining) {
554         mRemaining = 0;
555     } else {
556         LOG_ALWAYS_FATAL("Releasing more frames(%zu) than available(%zu)",
557                 pBuffer->frameCount, mRemaining);
558     }
559 
560     pBuffer->raw = NULL;
561     pBuffer->frameCount = 0;
562 }
563 
reset()564 void TimestretchBufferProvider::reset()
565 {
566     mRemaining = 0;
567 }
568 
setBufferProvider(AudioBufferProvider * p)569 void TimestretchBufferProvider::setBufferProvider(AudioBufferProvider *p) {
570     ALOGV("%s(%p): mTrackBufferProvider:%p  mBuffer.frameCount:%zu",
571             __func__, p, mTrackBufferProvider, mBuffer.frameCount);
572     if (mTrackBufferProvider == p) {
573         return;
574     }
575     mBuffer.frameCount = 0;
576     PassthruBufferProvider::setBufferProvider(p);
577 }
578 
setPlaybackRate(const AudioPlaybackRate & playbackRate)579 status_t TimestretchBufferProvider::setPlaybackRate(const AudioPlaybackRate &playbackRate)
580 {
581     mPlaybackRate = playbackRate;
582     mFallbackFailErrorShown = false;
583     sonicSetSpeed(mSonicStream, mPlaybackRate.mSpeed);
584     //TODO: pitch is ignored for now
585     //TODO: optimize: if parameters are the same, don't do any extra computation.
586 
587     mAudioPlaybackRateValid = isAudioPlaybackRateValid(mPlaybackRate);
588     return OK;
589 }
590 
processFrames(void * dstBuffer,size_t * dstFrames,const void * srcBuffer,size_t * srcFrames)591 void TimestretchBufferProvider::processFrames(void *dstBuffer, size_t *dstFrames,
592         const void *srcBuffer, size_t *srcFrames)
593 {
594     ALOGV("processFrames(%zu %zu)  remaining(%zu)", *dstFrames, *srcFrames, mRemaining);
595     // Note dstFrames is the required number of frames.
596 
597     if (!mAudioPlaybackRateValid) {
598         //fallback mode
599         // Ensure consumption from src is as expected.
600         // TODO: add logic to track "very accurate" consumption related to speed, original sampling
601         // rate, actual frames processed.
602 
603         const size_t targetSrc = *dstFrames * mPlaybackRate.mSpeed;
604         if (*srcFrames < targetSrc) { // limit dst frames to that possible
605             *dstFrames = *srcFrames / mPlaybackRate.mSpeed;
606         } else if (*srcFrames > targetSrc + 1) {
607             *srcFrames = targetSrc + 1;
608         }
609         if (*dstFrames > 0) {
610             switch(mPlaybackRate.mFallbackMode) {
611             case AUDIO_TIMESTRETCH_FALLBACK_CUT_REPEAT:
612                 if (*dstFrames <= *srcFrames) {
613                       size_t copySize = mFrameSize * *dstFrames;
614                       memcpy(dstBuffer, srcBuffer, copySize);
615                   } else {
616                       // cyclically repeat the source.
617                       for (size_t count = 0; count < *dstFrames; count += *srcFrames) {
618                           size_t remaining = std::min(*srcFrames, *dstFrames - count);
619                           memcpy((uint8_t*)dstBuffer + mFrameSize * count,
620                                   srcBuffer, mFrameSize * remaining);
621                       }
622                   }
623                 break;
624             case AUDIO_TIMESTRETCH_FALLBACK_DEFAULT:
625             case AUDIO_TIMESTRETCH_FALLBACK_MUTE:
626                 memset(dstBuffer,0, mFrameSize * *dstFrames);
627                 break;
628             case AUDIO_TIMESTRETCH_FALLBACK_FAIL:
629             default:
630                 if(!mFallbackFailErrorShown) {
631                     ALOGE("invalid parameters in TimestretchBufferProvider fallbackMode:%d",
632                             mPlaybackRate.mFallbackMode);
633                     mFallbackFailErrorShown = true;
634                 }
635                 break;
636             }
637         }
638     } else {
639         switch (mFormat) {
640         case AUDIO_FORMAT_PCM_FLOAT:
641             if (sonicWriteFloatToStream(mSonicStream, (float*)srcBuffer, *srcFrames) != 1) {
642                 ALOGE("sonicWriteFloatToStream cannot realloc");
643                 *srcFrames = 0; // cannot consume all of srcBuffer
644             }
645             *dstFrames = sonicReadFloatFromStream(mSonicStream, (float*)dstBuffer, *dstFrames);
646             break;
647         case AUDIO_FORMAT_PCM_16_BIT:
648             if (sonicWriteShortToStream(mSonicStream, (short*)srcBuffer, *srcFrames) != 1) {
649                 ALOGE("sonicWriteShortToStream cannot realloc");
650                 *srcFrames = 0; // cannot consume all of srcBuffer
651             }
652             *dstFrames = sonicReadShortFromStream(mSonicStream, (short*)dstBuffer, *dstFrames);
653             break;
654         default:
655             // could also be caught on construction
656             LOG_ALWAYS_FATAL("invalid format %#x for TimestretchBufferProvider", mFormat);
657         }
658     }
659 }
660 
AdjustChannelsBufferProvider(audio_format_t format,size_t inChannelCount,size_t outChannelCount,size_t frameCount,audio_format_t contractedFormat,void * contractedBuffer,size_t contractedOutChannelCount)661 AdjustChannelsBufferProvider::AdjustChannelsBufferProvider(
662         audio_format_t format, size_t inChannelCount, size_t outChannelCount,
663         size_t frameCount, audio_format_t contractedFormat, void* contractedBuffer,
664         size_t contractedOutChannelCount) :
665         CopyBufferProvider(
666                 audio_bytes_per_frame(inChannelCount, format),
667                 audio_bytes_per_frame(std::max(inChannelCount, outChannelCount), format),
668                 frameCount),
669         mFormat(format),
670         mInChannelCount(inChannelCount),
671         mOutChannelCount(outChannelCount),
672         mSampleSizeInBytes(audio_bytes_per_sample(format)),
673         mFrameCount(frameCount),
674         mContractedFormat(inChannelCount > outChannelCount
675                 ? contractedFormat : AUDIO_FORMAT_INVALID),
676         mContractedInChannelCount(inChannelCount > outChannelCount
677                 ? inChannelCount - outChannelCount : 0),
678         mContractedOutChannelCount(contractedOutChannelCount),
679         mContractedSampleSizeInBytes(audio_bytes_per_sample(contractedFormat)),
680         mContractedInputFrameSize(mContractedInChannelCount * mContractedSampleSizeInBytes),
681         mContractedBuffer(contractedBuffer),
682         mContractedWrittenFrames(0)
683 {
684     ALOGV("AdjustChannelsBufferProvider(%p)(%#x, %zu, %zu, %zu, %#x, %p, %zu)",
685           this, format, inChannelCount, outChannelCount, frameCount, contractedFormat,
686           contractedBuffer, contractedOutChannelCount);
687     if (mContractedFormat != AUDIO_FORMAT_INVALID && mInChannelCount > mOutChannelCount) {
688         mContractedOutputFrameSize =
689                 audio_bytes_per_frame(mContractedOutChannelCount, mContractedFormat);
690     }
691 }
692 
getNextBuffer(AudioBufferProvider::Buffer * pBuffer)693 status_t AdjustChannelsBufferProvider::getNextBuffer(AudioBufferProvider::Buffer* pBuffer)
694 {
695     if (mContractedBuffer != nullptr) {
696         // Restrict frame count only when it is needed to save contracted frames.
697         const size_t outFramesLeft = mFrameCount - mContractedWrittenFrames;
698         if (outFramesLeft < pBuffer->frameCount) {
699             // Restrict the frame count so that we don't write over the size of the output buffer.
700             pBuffer->frameCount = outFramesLeft;
701         }
702     }
703     return CopyBufferProvider::getNextBuffer(pBuffer);
704 }
705 
copyFrames(void * dst,const void * src,size_t frames)706 void AdjustChannelsBufferProvider::copyFrames(void *dst, const void *src, size_t frames)
707 {
708     // For case multi to mono, adjust_channels has special logic that will mix first two input
709     // channels into a single output channel. In that case, use adjust_channels_non_destructive
710     // to keep only one channel data even when contracting to mono.
711     adjust_channels_non_destructive(src, mInChannelCount, dst, mOutChannelCount,
712             mSampleSizeInBytes, frames * mInChannelCount * mSampleSizeInBytes);
713     if (mContractedFormat != AUDIO_FORMAT_INVALID
714         && mContractedBuffer != nullptr) {
715         const size_t contractedIdx = frames * mOutChannelCount * mSampleSizeInBytes;
716         uint8_t* oriBuf = (uint8_t*) dst + contractedIdx;
717         uint8_t* buf = (uint8_t*) mContractedBuffer
718                 + mContractedWrittenFrames * mContractedOutputFrameSize;
719         if (mContractedInChannelCount > mContractedOutChannelCount) {
720             // Adjust the channels first as the contracted buffer may not have enough
721             // space for the data.
722             // Use adjust_channels_non_destructive to avoid mix first two channels into one single
723             // output channel when it is multi to mono.
724             adjust_channels_non_destructive(
725                     oriBuf, mContractedInChannelCount, oriBuf, mContractedOutChannelCount,
726                     mSampleSizeInBytes, frames * mContractedInChannelCount * mSampleSizeInBytes);
727             memcpy_by_audio_format(
728                     buf, mContractedFormat, oriBuf, mFormat, mContractedOutChannelCount * frames);
729         } else {
730             // Copy the data first as the dst buffer may not have enough space for extra channel.
731             memcpy_by_audio_format(
732                 buf, mContractedFormat, oriBuf, mFormat, mContractedInChannelCount * frames);
733             // Note that if the contracted data is from MONO to MULTICHANNEL, the first 2 channels
734             // will be duplicated with the original single input channel and all the other channels
735             // will be 0-filled.
736             adjust_channels(
737                     buf, mContractedInChannelCount, buf, mContractedOutChannelCount,
738                     mContractedSampleSizeInBytes, mContractedInputFrameSize * frames);
739         }
740         mContractedWrittenFrames += frames;
741     }
742 }
743 
reset()744 void AdjustChannelsBufferProvider::reset()
745 {
746     mContractedWrittenFrames = 0;
747     CopyBufferProvider::reset();
748 }
749 
copyFrames(void * dst,const void * src,size_t frames)750 void TeeBufferProvider::copyFrames(void *dst, const void *src, size_t frames) {
751     memcpy(dst, src, frames * mInputFrameSize);
752     if (int teeBufferFrameLeft = mTeeBufferFrameCount - mFrameCopied; teeBufferFrameLeft < frames) {
753         ALOGW("Unable to copy all frames to tee buffer, %d frames dropped",
754               (int)frames - teeBufferFrameLeft);
755         frames = teeBufferFrameLeft;
756     }
757     memcpy(mTeeBuffer + mFrameCopied * mInputFrameSize, src, frames * mInputFrameSize);
758     mFrameCopied += frames;
759 }
760 
clearFramesCopied()761 void TeeBufferProvider::clearFramesCopied() {
762     mFrameCopied = 0;
763 }
764 
765 // ----------------------------------------------------------------------------
766 } // namespace android
767