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