1 /*
2  * Copyright (C) 2010 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 #include <inttypes.h>
18 #include <stdlib.h>
19 
20 //#define LOG_NDEBUG 0
21 #define LOG_TAG "AudioSource"
22 #include <utils/Log.h>
23 
24 #include <binder/IPCThreadState.h>
25 #include <media/AidlConversion.h>
26 #include <media/AudioRecord.h>
27 #include <media/stagefright/AudioSource.h>
28 #include <media/stagefright/MediaBuffer.h>
29 #include <media/stagefright/MediaDefs.h>
30 #include <media/stagefright/MetaData.h>
31 #include <media/stagefright/foundation/ADebug.h>
32 #include <media/stagefright/foundation/ALooper.h>
33 #include <cutils/properties.h>
34 
35 namespace android {
36 
37 using content::AttributionSourceState;
38 
39 
onOverrun()40 void AudioSource::onOverrun() {
41     ALOGW("AudioRecord reported overrun!");
42 }
43 
AudioSource(const audio_attributes_t * attr,const AttributionSourceState & attributionSource,uint32_t sampleRate,uint32_t channelCount,uint32_t outSampleRate,audio_port_handle_t selectedDeviceId,audio_microphone_direction_t selectedMicDirection,float selectedMicFieldDimension)44 AudioSource::AudioSource(
45     const audio_attributes_t *attr, const AttributionSourceState& attributionSource,
46     uint32_t sampleRate, uint32_t channelCount, uint32_t outSampleRate,
47     audio_port_handle_t selectedDeviceId,
48     audio_microphone_direction_t selectedMicDirection,
49     float selectedMicFieldDimension)
50 {
51   set(attr, attributionSource, sampleRate, channelCount, outSampleRate, selectedDeviceId,
52       selectedMicDirection, selectedMicFieldDimension);
53 }
54 
AudioSource(const audio_attributes_t * attr,const String16 & opPackageName,uint32_t sampleRate,uint32_t channelCount,uint32_t outSampleRate,uid_t uid,pid_t pid,audio_port_handle_t selectedDeviceId,audio_microphone_direction_t selectedMicDirection,float selectedMicFieldDimension)55 AudioSource::AudioSource(
56         const audio_attributes_t *attr, const String16 &opPackageName,
57         uint32_t sampleRate, uint32_t channelCount, uint32_t outSampleRate,
58         uid_t uid, pid_t pid, audio_port_handle_t selectedDeviceId,
59         audio_microphone_direction_t selectedMicDirection,
60         float selectedMicFieldDimension)
61 {
62     // TODO b/182392769: use attribution source util
63     AttributionSourceState attributionSource;
64     attributionSource.packageName = VALUE_OR_FATAL(legacy2aidl_String16_string(opPackageName));
65     attributionSource.uid = VALUE_OR_FATAL(legacy2aidl_uid_t_int32_t(uid));
66     attributionSource.pid = VALUE_OR_FATAL(legacy2aidl_pid_t_int32_t(pid));
67     attributionSource.token = sp<BBinder>::make();
68     set(attr, attributionSource, sampleRate, channelCount, outSampleRate, selectedDeviceId,
69       selectedMicDirection, selectedMicFieldDimension);
70 }
71 
set(const audio_attributes_t * attr,const AttributionSourceState & attributionSource,uint32_t sampleRate,uint32_t channelCount,uint32_t outSampleRate,audio_port_handle_t selectedDeviceId,audio_microphone_direction_t selectedMicDirection,float selectedMicFieldDimension)72 void AudioSource::set(
73    const audio_attributes_t *attr, const AttributionSourceState& attributionSource,
74         uint32_t sampleRate, uint32_t channelCount, uint32_t outSampleRate,
75         audio_port_handle_t selectedDeviceId,
76         audio_microphone_direction_t selectedMicDirection,
77         float selectedMicFieldDimension)
78 {
79    mStarted = false;
80    mSampleRate = sampleRate;
81    mOutSampleRate = outSampleRate > 0 ? outSampleRate : sampleRate;
82    mTrackMaxAmplitude = false;
83    mStartTimeUs = 0;
84    mStopSystemTimeUs = -1;
85    mLastFrameTimestampUs = 0;
86    mMaxAmplitude = 0;
87    mPrevSampleTimeUs = 0;
88    mInitialReadTimeUs = 0;
89    mNumFramesReceived = 0;
90    mNumFramesSkipped = 0;
91    mNumFramesLost = 0;
92    mNumClientOwnedBuffers = 0;
93    mNoMoreFramesToRead = false;
94   ALOGV("sampleRate: %u, outSampleRate: %u, channelCount: %u",
95         sampleRate, outSampleRate, channelCount);
96   CHECK(channelCount == 1 || channelCount == 2);
97   CHECK(sampleRate > 0);
98 
99   size_t minFrameCount;
100   status_t status = AudioRecord::getMinFrameCount(&minFrameCount,
101                                                   sampleRate,
102                                                   AUDIO_FORMAT_PCM_16_BIT,
103                                                   audio_channel_in_mask_from_count(channelCount));
104   if (status == OK) {
105     // make sure that the AudioRecord callback never returns more than the maximum
106     // buffer size
107     uint32_t frameCount = kMaxBufferSize / sizeof(int16_t) / channelCount;
108 
109     // make sure that the AudioRecord total buffer size is large enough
110     size_t bufCount = 2;
111     while ((bufCount * frameCount) < minFrameCount) {
112       bufCount++;
113     }
114 
115     mRecord = new AudioRecord(
116         AUDIO_SOURCE_DEFAULT, sampleRate, AUDIO_FORMAT_PCM_16_BIT,
117         audio_channel_in_mask_from_count(channelCount),
118         attributionSource,
119         (size_t) (bufCount * frameCount),
120         wp<AudioRecord::IAudioRecordCallback>{this},
121         frameCount /*notificationFrames*/,
122         AUDIO_SESSION_ALLOCATE,
123         AudioRecord::TRANSFER_DEFAULT,
124         AUDIO_INPUT_FLAG_NONE,
125         attr,
126         selectedDeviceId,
127         selectedMicDirection,
128         selectedMicFieldDimension);
129     // Set caller name so it can be logged in destructor.
130     // MediaMetricsConstants.h: AMEDIAMETRICS_PROP_CALLERNAME_VALUE_MEDIA
131     mRecord->setCallerName("media");
132     mInitCheck = mRecord->initCheck();
133     if (mInitCheck != OK) {
134       mRecord.clear();
135     }
136   } else {
137     mInitCheck = status;
138   }
139 }
140 
~AudioSource()141 AudioSource::~AudioSource() {
142     if (mStarted) {
143         reset();
144     }
145 }
146 
initCheck() const147 status_t AudioSource::initCheck() const {
148     return mInitCheck;
149 }
150 
start(MetaData * params)151 status_t AudioSource::start(MetaData *params) {
152     Mutex::Autolock autoLock(mLock);
153     if (mStarted) {
154         return UNKNOWN_ERROR;
155     }
156 
157     if (mInitCheck != OK) {
158         return NO_INIT;
159     }
160 
161     mTrackMaxAmplitude = false;
162     mMaxAmplitude = 0;
163     mInitialReadTimeUs = 0;
164     mStartTimeUs = 0;
165     int64_t startTimeUs;
166     if (params && params->findInt64(kKeyTime, &startTimeUs)) {
167         mStartTimeUs = startTimeUs;
168     }
169     status_t err = mRecord->start();
170     if (err == OK) {
171         mStarted = true;
172     } else {
173         mRecord.clear();
174     }
175 
176 
177     return err;
178 }
179 
releaseQueuedFrames_l()180 void AudioSource::releaseQueuedFrames_l() {
181     ALOGV("releaseQueuedFrames_l");
182     List<MediaBuffer *>::iterator it;
183     while (!mBuffersReceived.empty()) {
184         it = mBuffersReceived.begin();
185         (*it)->release();
186         mBuffersReceived.erase(it);
187     }
188 }
189 
waitOutstandingEncodingFrames_l()190 void AudioSource::waitOutstandingEncodingFrames_l() {
191     ALOGV("waitOutstandingEncodingFrames_l: %" PRId64, mNumClientOwnedBuffers);
192     while (mNumClientOwnedBuffers > 0) {
193         mFrameEncodingCompletionCondition.wait(mLock);
194     }
195 }
196 
reset()197 status_t AudioSource::reset() {
198     Mutex::Autolock autoLock(mLock);
199     if (!mStarted) {
200         return UNKNOWN_ERROR;
201     }
202 
203     if (mInitCheck != OK) {
204         return NO_INIT;
205     }
206 
207     mStarted = false;
208     mStopSystemTimeUs = -1;
209     mNoMoreFramesToRead = false;
210     mFrameAvailableCondition.signal();
211 
212     mRecord->stop();
213     waitOutstandingEncodingFrames_l();
214     releaseQueuedFrames_l();
215 
216     return OK;
217 }
218 
getFormat()219 sp<MetaData> AudioSource::getFormat() {
220     Mutex::Autolock autoLock(mLock);
221     if (mInitCheck != OK) {
222         return 0;
223     }
224 
225     sp<MetaData> meta = new MetaData;
226     meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
227     meta->setInt32(kKeySampleRate, mSampleRate);
228     meta->setInt32(kKeyChannelCount, mRecord->channelCount());
229     meta->setInt32(kKeyMaxInputSize, kMaxBufferSize);
230     meta->setInt32(kKeyPcmEncoding, kAudioEncodingPcm16bit);
231 
232     return meta;
233 }
234 
rampVolume(int32_t startFrame,int32_t rampDurationFrames,uint8_t * data,size_t bytes)235 void AudioSource::rampVolume(
236         int32_t startFrame, int32_t rampDurationFrames,
237         uint8_t *data,   size_t bytes) {
238 
239     const int32_t kShift = 14;
240     int32_t fixedMultiplier = (startFrame << kShift) / rampDurationFrames;
241     const int32_t nChannels = mRecord->channelCount();
242     int32_t stopFrame = startFrame + bytes / sizeof(int16_t);
243     int16_t *frame = (int16_t *) data;
244     if (stopFrame > rampDurationFrames) {
245         stopFrame = rampDurationFrames;
246     }
247 
248     while (startFrame < stopFrame) {
249         if (nChannels == 1) {  // mono
250             frame[0] = (frame[0] * fixedMultiplier) >> kShift;
251             ++frame;
252             ++startFrame;
253         } else {               // stereo
254             frame[0] = (frame[0] * fixedMultiplier) >> kShift;
255             frame[1] = (frame[1] * fixedMultiplier) >> kShift;
256             frame += 2;
257             startFrame += 2;
258         }
259 
260         // Update the multiplier every 4 frames
261         if ((startFrame & 3) == 0) {
262             fixedMultiplier = (startFrame << kShift) / rampDurationFrames;
263         }
264     }
265 }
266 
read(MediaBufferBase ** out,const ReadOptions *)267 status_t AudioSource::read(
268         MediaBufferBase **out, const ReadOptions * /* options */) {
269     Mutex::Autolock autoLock(mLock);
270     *out = NULL;
271 
272     if (mInitCheck != OK) {
273         return NO_INIT;
274     }
275 
276     while (mStarted && mBuffersReceived.empty()) {
277         mFrameAvailableCondition.wait(mLock);
278         if (mNoMoreFramesToRead) {
279             return OK;
280         }
281     }
282     if (!mStarted) {
283         return OK;
284     }
285     MediaBuffer *buffer = *mBuffersReceived.begin();
286     mBuffersReceived.erase(mBuffersReceived.begin());
287     ++mNumClientOwnedBuffers;
288     buffer->setObserver(this);
289     buffer->add_ref();
290 
291     // Mute/suppress the recording sound
292     int64_t timeUs;
293     CHECK(buffer->meta_data().findInt64(kKeyTime, &timeUs));
294     int64_t elapsedTimeUs = timeUs - mStartTimeUs;
295     if (elapsedTimeUs < kAutoRampStartUs) {
296         memset((uint8_t *) buffer->data(), 0, buffer->range_length());
297     } else if (elapsedTimeUs < kAutoRampStartUs + kAutoRampDurationUs) {
298         int32_t autoRampDurationFrames =
299                     ((int64_t)kAutoRampDurationUs * mSampleRate + 500000LL) / 1000000LL; //Need type casting
300 
301         int32_t autoRampStartFrames =
302                     ((int64_t)kAutoRampStartUs * mSampleRate + 500000LL) / 1000000LL; //Need type casting
303 
304         int32_t nFrames = mNumFramesReceived - autoRampStartFrames;
305         rampVolume(nFrames, autoRampDurationFrames,
306                 (uint8_t *) buffer->data(), buffer->range_length());
307     }
308 
309     // Track the max recording signal amplitude.
310     if (mTrackMaxAmplitude) {
311         trackMaxAmplitude(
312             (int16_t *) buffer->data(), buffer->range_length() >> 1);
313     }
314 
315     if (mSampleRate != mOutSampleRate) {
316             timeUs *= (int64_t)mSampleRate / (int64_t)mOutSampleRate;
317             buffer->meta_data().setInt64(kKeyTime, timeUs);
318     }
319 
320     *out = buffer;
321     return OK;
322 }
323 
setStopTimeUs(int64_t stopTimeUs)324 status_t AudioSource::setStopTimeUs(int64_t stopTimeUs) {
325     Mutex::Autolock autoLock(mLock);
326     ALOGV("Set stoptime: %lld us", (long long)stopTimeUs);
327 
328     if (stopTimeUs < -1) {
329         ALOGE("Invalid stop time %lld us", (long long)stopTimeUs);
330         return BAD_VALUE;
331     } else if (stopTimeUs == -1) {
332         ALOGI("reset stopTime to be -1");
333     }
334 
335     mStopSystemTimeUs = stopTimeUs;
336     return OK;
337 }
338 
signalBufferReturned(MediaBufferBase * buffer)339 void AudioSource::signalBufferReturned(MediaBufferBase *buffer) {
340     ALOGV("signalBufferReturned: %p", buffer->data());
341     Mutex::Autolock autoLock(mLock);
342     --mNumClientOwnedBuffers;
343     buffer->setObserver(0);
344     buffer->release();
345     mFrameEncodingCompletionCondition.signal();
346     return;
347 }
348 
onMoreData(const AudioRecord::Buffer & audioBuffer)349 size_t AudioSource::onMoreData(const AudioRecord::Buffer& audioBuffer) {
350     int64_t timeUs, position, timeNs;
351     ExtendedTimestamp ts;
352     ExtendedTimestamp::Location location;
353     const int32_t usPerSec = 1000000;
354 
355     if (mRecord->getTimestamp(&ts) == OK &&
356             ts.getBestTimestamp(&position, &timeNs, ExtendedTimestamp::TIMEBASE_MONOTONIC,
357             &location) == OK) {
358         // Use audio timestamp.
359         timeUs = timeNs / 1000 -
360                 (position - mNumFramesSkipped -
361                 mNumFramesReceived + mNumFramesLost) * usPerSec / mSampleRate;
362     } else {
363         // This should not happen in normal case.
364         ALOGW("Failed to get audio timestamp, fallback to use systemclock");
365         timeUs = systemTime() / 1000LL;
366         // Estimate the real sampling time of the 1st sample in this buffer
367         // from AudioRecord's latency. (Apply this adjustment first so that
368         // the start time logic is not affected.)
369         timeUs -= mRecord->latency() * 1000LL;
370     }
371 
372     ALOGV("dataCallbackTimestamp: %" PRId64 " us", timeUs);
373     Mutex::Autolock autoLock(mLock);
374 
375     if (!mStarted) {
376         ALOGW("Spurious callback from AudioRecord. Drop the audio data.");
377         return audioBuffer.size();
378     }
379 
380 
381     // Drop retrieved and previously lost audio data.
382     if (mNumFramesReceived == 0 && timeUs < mStartTimeUs) {
383         (void) mRecord->getInputFramesLost();
384         int64_t receievedFrames = audioBuffer.size() / mRecord->frameSize();
385         ALOGV("Drop audio data(%" PRId64 " frames) at %" PRId64 "/%" PRId64 " us",
386                 receievedFrames, timeUs, mStartTimeUs);
387         mNumFramesSkipped += receievedFrames;
388         return audioBuffer.size();
389     }
390 
391     if (mStopSystemTimeUs != -1 && timeUs >= mStopSystemTimeUs) {
392         ALOGV("Drop Audio frame at %lld  stop time: %lld us",
393                 (long long)timeUs, (long long)mStopSystemTimeUs);
394         mNoMoreFramesToRead = true;
395         mFrameAvailableCondition.signal();
396         return audioBuffer.size();
397     }
398 
399     if (mNumFramesReceived == 0 && mPrevSampleTimeUs == 0) {
400         mInitialReadTimeUs = timeUs;
401         // Initial delay
402         if (mStartTimeUs > 0) {
403             mStartTimeUs = timeUs - mStartTimeUs;
404         }
405         mPrevSampleTimeUs = mStartTimeUs;
406     }
407     mLastFrameTimestampUs = timeUs;
408 
409     uint64_t numLostBytes = 0; // AudioRecord::getInputFramesLost() returns uint32_t
410     if (mNumFramesReceived > 0) {  // Ignore earlier frame lost
411         // getInputFramesLost() returns the number of lost frames.
412         // Convert number of frames lost to number of bytes lost.
413         numLostBytes = (uint64_t)mRecord->getInputFramesLost() * mRecord->frameSize();
414     }
415 
416     CHECK_EQ(numLostBytes & 1, 0u);
417     CHECK_EQ(audioBuffer.size() & 1, 0u);
418     if (numLostBytes > 0) {
419         // Loss of audio frames should happen rarely; thus the LOGW should
420         // not cause a logging spam
421         ALOGW("Lost audio record data: %" PRIu64 " bytes", numLostBytes);
422     }
423 
424     while (numLostBytes > 0) {
425         uint64_t bufferSize = numLostBytes;
426         if (numLostBytes > kMaxBufferSize) {
427             numLostBytes -= kMaxBufferSize;
428             bufferSize = kMaxBufferSize;
429         } else {
430             numLostBytes = 0;
431         }
432         MediaBuffer *lostAudioBuffer = new MediaBuffer(bufferSize);
433         memset(lostAudioBuffer->data(), 0, bufferSize);
434         lostAudioBuffer->set_range(0, bufferSize);
435         mNumFramesLost += bufferSize / mRecord->frameSize();
436         queueInputBuffer_l(lostAudioBuffer, timeUs);
437     }
438 
439     if (audioBuffer.size() == 0) {
440         ALOGW("Nothing is available from AudioRecord callback buffer");
441         return audioBuffer.size();
442     }
443 
444     MediaBuffer *buffer = new MediaBuffer(audioBuffer.size());
445     memcpy((uint8_t *) buffer->data(),
446             audioBuffer.data(), audioBuffer.size());
447     buffer->set_range(0, audioBuffer.size());
448     queueInputBuffer_l(buffer, timeUs);
449     return audioBuffer.size();
450 }
451 
queueInputBuffer_l(MediaBuffer * buffer,int64_t timeUs)452 void AudioSource::queueInputBuffer_l(MediaBuffer *buffer, int64_t timeUs) {
453     const size_t bufferSize = buffer->range_length();
454     const size_t frameSize = mRecord->frameSize();
455     if (mNumFramesReceived == 0) {
456         buffer->meta_data().setInt64(kKeyAnchorTime, mStartTimeUs);
457     }
458     mNumFramesReceived += bufferSize / frameSize;
459     const int64_t timestampUs =
460                 mStartTimeUs +
461                     ((1000000LL * mNumFramesReceived) +
462                         (mSampleRate >> 1)) / mSampleRate;
463     buffer->meta_data().setInt64(kKeyTime, mPrevSampleTimeUs);
464     buffer->meta_data().setInt64(kKeyDriftTime, timeUs - mInitialReadTimeUs);
465     mPrevSampleTimeUs = timestampUs;
466     mBuffersReceived.push_back(buffer);
467     mFrameAvailableCondition.signal();
468 }
469 
trackMaxAmplitude(int16_t * data,int nSamples)470 void AudioSource::trackMaxAmplitude(int16_t *data, int nSamples) {
471     for (int i = nSamples; i > 0; --i) {
472         int16_t value = *data++;
473         if (value < 0) {
474             value = -value;
475         }
476         if (mMaxAmplitude < value) {
477             mMaxAmplitude = value;
478         }
479     }
480 }
481 
getMaxAmplitude()482 int16_t AudioSource::getMaxAmplitude() {
483     // First call activates the tracking.
484     if (!mTrackMaxAmplitude) {
485         mTrackMaxAmplitude = true;
486     }
487     int16_t value = mMaxAmplitude;
488     mMaxAmplitude = 0;
489     ALOGV("max amplitude since last call: %d", value);
490     return value;
491 }
492 
setInputDevice(audio_port_handle_t deviceId)493 status_t AudioSource::setInputDevice(audio_port_handle_t deviceId) {
494     if (mRecord != 0) {
495         return mRecord->setInputDevice(deviceId);
496     }
497     return NO_INIT;
498 }
499 
getRoutedDeviceId(audio_port_handle_t * deviceId)500 status_t AudioSource::getRoutedDeviceId(audio_port_handle_t* deviceId) {
501     if (mRecord != 0) {
502         *deviceId = mRecord->getRoutedDeviceId();
503         return NO_ERROR;
504     }
505     return NO_INIT;
506 }
507 
addAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback> & callback)508 status_t AudioSource::addAudioDeviceCallback(
509         const sp<AudioSystem::AudioDeviceCallback>& callback) {
510     if (mRecord != 0) {
511         return mRecord->addAudioDeviceCallback(callback);
512     }
513     return NO_INIT;
514 }
515 
removeAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback> & callback)516 status_t AudioSource::removeAudioDeviceCallback(
517         const sp<AudioSystem::AudioDeviceCallback>& callback) {
518     if (mRecord != 0) {
519         return mRecord->removeAudioDeviceCallback(callback);
520     }
521     return NO_INIT;
522 }
523 
getActiveMicrophones(std::vector<media::MicrophoneInfoFw> * activeMicrophones)524 status_t AudioSource::getActiveMicrophones(
525         std::vector<media::MicrophoneInfoFw>* activeMicrophones) {
526     if (mRecord != 0) {
527         return mRecord->getActiveMicrophones(activeMicrophones);
528     }
529     return NO_INIT;
530 }
531 
setPreferredMicrophoneDirection(audio_microphone_direction_t direction)532 status_t AudioSource::setPreferredMicrophoneDirection(audio_microphone_direction_t direction) {
533     ALOGV("setPreferredMicrophoneDirection(%d)", direction);
534     if (mRecord != 0) {
535         return mRecord->setPreferredMicrophoneDirection(direction);
536     }
537     return NO_INIT;
538 }
539 
setPreferredMicrophoneFieldDimension(float zoom)540 status_t AudioSource::setPreferredMicrophoneFieldDimension(float zoom) {
541     ALOGV("setPreferredMicrophoneFieldDimension(%f)", zoom);
542     if (mRecord != 0) {
543         return mRecord->setPreferredMicrophoneFieldDimension(zoom);
544     }
545     return NO_INIT;
546 }
547 
getPortId(audio_port_handle_t * portId) const548 status_t AudioSource::getPortId(audio_port_handle_t *portId) const {
549     if (mRecord != 0) {
550         *portId = mRecord->getPortId();
551         return NO_ERROR;
552     }
553     return NO_INIT;
554 }
555 }  // namespace android
556