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