summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/AudioSource.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/AudioSource.cpp')
-rw-r--r--media/libstagefright/AudioSource.cpp372
1 files changed, 0 insertions, 372 deletions
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
deleted file mode 100644
index 0f1d841..0000000
--- a/media/libstagefright/AudioSource.cpp
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "AudioSource"
-#include <utils/Log.h>
-
-#include <media/AudioRecord.h>
-#include <media/stagefright/AudioSource.h>
-#include <media/stagefright/MediaBuffer.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MetaData.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <cutils/properties.h>
-#include <stdlib.h>
-
-namespace android {
-
-static void AudioRecordCallbackFunction(int event, void *user, void *info) {
- AudioSource *source = (AudioSource *) user;
- switch (event) {
- case AudioRecord::EVENT_MORE_DATA: {
- source->dataCallbackTimestamp(*((AudioRecord::Buffer *) info), systemTime() / 1000);
- break;
- }
- case AudioRecord::EVENT_OVERRUN: {
- ALOGW("AudioRecord reported overrun!");
- break;
- }
- default:
- // does nothing
- break;
- }
-}
-
-AudioSource::AudioSource(
- audio_source_t inputSource, uint32_t sampleRate, uint32_t channelCount)
- : mStarted(false),
- mSampleRate(sampleRate),
- mPrevSampleTimeUs(0),
- mNumFramesReceived(0),
- mNumClientOwnedBuffers(0) {
-
- ALOGV("sampleRate: %d, channelCount: %d", sampleRate, channelCount);
- CHECK(channelCount == 1 || channelCount == 2);
- AudioRecord::record_flags flags = (AudioRecord::record_flags)
- (AudioRecord::RECORD_AGC_ENABLE |
- AudioRecord::RECORD_NS_ENABLE |
- AudioRecord::RECORD_IIR_ENABLE);
- mRecord = new AudioRecord(
- inputSource, sampleRate, AUDIO_FORMAT_PCM_16_BIT,
- audio_channel_in_mask_from_count(channelCount),
- 4 * kMaxBufferSize / sizeof(int16_t), /* Enable ping-pong buffers */
- flags,
- AudioRecordCallbackFunction,
- this);
-
- mInitCheck = mRecord->initCheck();
-}
-
-AudioSource::~AudioSource() {
- if (mStarted) {
- reset();
- }
-
- delete mRecord;
- mRecord = NULL;
-}
-
-status_t AudioSource::initCheck() const {
- return mInitCheck;
-}
-
-status_t AudioSource::start(MetaData *params) {
- Mutex::Autolock autoLock(mLock);
- if (mStarted) {
- return UNKNOWN_ERROR;
- }
-
- if (mInitCheck != OK) {
- return NO_INIT;
- }
-
- mTrackMaxAmplitude = false;
- mMaxAmplitude = 0;
- mInitialReadTimeUs = 0;
- mStartTimeUs = 0;
- int64_t startTimeUs;
- if (params && params->findInt64(kKeyTime, &startTimeUs)) {
- mStartTimeUs = startTimeUs;
- }
- status_t err = mRecord->start();
- if (err == OK) {
- mStarted = true;
- } else {
- delete mRecord;
- mRecord = NULL;
- }
-
-
- return err;
-}
-
-void AudioSource::releaseQueuedFrames_l() {
- ALOGV("releaseQueuedFrames_l");
- List<MediaBuffer *>::iterator it;
- while (!mBuffersReceived.empty()) {
- it = mBuffersReceived.begin();
- (*it)->release();
- mBuffersReceived.erase(it);
- }
-}
-
-void AudioSource::waitOutstandingEncodingFrames_l() {
- ALOGV("waitOutstandingEncodingFrames_l: %lld", mNumClientOwnedBuffers);
- while (mNumClientOwnedBuffers > 0) {
- mFrameEncodingCompletionCondition.wait(mLock);
- }
-}
-
-status_t AudioSource::reset() {
- Mutex::Autolock autoLock(mLock);
- if (!mStarted) {
- return UNKNOWN_ERROR;
- }
-
- if (mInitCheck != OK) {
- return NO_INIT;
- }
-
- mStarted = false;
- mRecord->stop();
- waitOutstandingEncodingFrames_l();
- releaseQueuedFrames_l();
-
- return OK;
-}
-
-sp<MetaData> AudioSource::getFormat() {
- Mutex::Autolock autoLock(mLock);
- if (mInitCheck != OK) {
- return 0;
- }
-
- sp<MetaData> meta = new MetaData;
- meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
- meta->setInt32(kKeySampleRate, mSampleRate);
- meta->setInt32(kKeyChannelCount, mRecord->channelCount());
- meta->setInt32(kKeyMaxInputSize, kMaxBufferSize);
-
- return meta;
-}
-
-void AudioSource::rampVolume(
- int32_t startFrame, int32_t rampDurationFrames,
- uint8_t *data, size_t bytes) {
-
- const int32_t kShift = 14;
- int32_t fixedMultiplier = (startFrame << kShift) / rampDurationFrames;
- const int32_t nChannels = mRecord->channelCount();
- int32_t stopFrame = startFrame + bytes / sizeof(int16_t);
- int16_t *frame = (int16_t *) data;
- if (stopFrame > rampDurationFrames) {
- stopFrame = rampDurationFrames;
- }
-
- while (startFrame < stopFrame) {
- if (nChannels == 1) { // mono
- frame[0] = (frame[0] * fixedMultiplier) >> kShift;
- ++frame;
- ++startFrame;
- } else { // stereo
- frame[0] = (frame[0] * fixedMultiplier) >> kShift;
- frame[1] = (frame[1] * fixedMultiplier) >> kShift;
- frame += 2;
- startFrame += 2;
- }
-
- // Update the multiplier every 4 frames
- if ((startFrame & 3) == 0) {
- fixedMultiplier = (startFrame << kShift) / rampDurationFrames;
- }
- }
-}
-
-status_t AudioSource::read(
- MediaBuffer **out, const ReadOptions *options) {
- Mutex::Autolock autoLock(mLock);
- *out = NULL;
-
- if (mInitCheck != OK) {
- return NO_INIT;
- }
-
- while (mStarted && mBuffersReceived.empty()) {
- mFrameAvailableCondition.wait(mLock);
- }
- if (!mStarted) {
- return OK;
- }
- MediaBuffer *buffer = *mBuffersReceived.begin();
- mBuffersReceived.erase(mBuffersReceived.begin());
- ++mNumClientOwnedBuffers;
- buffer->setObserver(this);
- buffer->add_ref();
-
- // Mute/suppress the recording sound
- int64_t timeUs;
- CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
- int64_t elapsedTimeUs = timeUs - mStartTimeUs;
- if (elapsedTimeUs < kAutoRampStartUs) {
- memset((uint8_t *) buffer->data(), 0, buffer->range_length());
- } else if (elapsedTimeUs < kAutoRampStartUs + kAutoRampDurationUs) {
- int32_t autoRampDurationFrames =
- (kAutoRampDurationUs * mSampleRate + 500000LL) / 1000000LL;
-
- int32_t autoRampStartFrames =
- (kAutoRampStartUs * mSampleRate + 500000LL) / 1000000LL;
-
- int32_t nFrames = mNumFramesReceived - autoRampStartFrames;
- rampVolume(nFrames, autoRampDurationFrames,
- (uint8_t *) buffer->data(), buffer->range_length());
- }
-
- // Track the max recording signal amplitude.
- if (mTrackMaxAmplitude) {
- trackMaxAmplitude(
- (int16_t *) buffer->data(), buffer->range_length() >> 1);
- }
-
- *out = buffer;
- return OK;
-}
-
-void AudioSource::signalBufferReturned(MediaBuffer *buffer) {
- ALOGV("signalBufferReturned: %p", buffer->data());
- Mutex::Autolock autoLock(mLock);
- --mNumClientOwnedBuffers;
- buffer->setObserver(0);
- buffer->release();
- mFrameEncodingCompletionCondition.signal();
- return;
-}
-
-status_t AudioSource::dataCallbackTimestamp(
- const AudioRecord::Buffer& audioBuffer, int64_t timeUs) {
- ALOGV("dataCallbackTimestamp: %lld us", timeUs);
- Mutex::Autolock autoLock(mLock);
- if (!mStarted) {
- ALOGW("Spurious callback from AudioRecord. Drop the audio data.");
- return OK;
- }
-
- // Drop retrieved and previously lost audio data.
- if (mNumFramesReceived == 0 && timeUs < mStartTimeUs) {
- mRecord->getInputFramesLost();
- ALOGV("Drop audio data at %lld/%lld us", timeUs, mStartTimeUs);
- return OK;
- }
-
- if (mNumFramesReceived == 0 && mPrevSampleTimeUs == 0) {
- mInitialReadTimeUs = timeUs;
- // Initial delay
- if (mStartTimeUs > 0) {
- mStartTimeUs = timeUs - mStartTimeUs;
- } else {
- // Assume latency is constant.
- mStartTimeUs += mRecord->latency() * 1000;
- }
- mPrevSampleTimeUs = mStartTimeUs;
- }
-
- size_t numLostBytes = 0;
- if (mNumFramesReceived > 0) { // Ignore earlier frame lost
- // getInputFramesLost() returns the number of lost frames.
- // Convert number of frames lost to number of bytes lost.
- numLostBytes = mRecord->getInputFramesLost() * mRecord->frameSize();
- }
-
- CHECK_EQ(numLostBytes & 1, 0u);
- CHECK_EQ(audioBuffer.size & 1, 0u);
- if (numLostBytes > 0) {
- // Loss of audio frames should happen rarely; thus the LOGW should
- // not cause a logging spam
- ALOGW("Lost audio record data: %d bytes", numLostBytes);
- }
-
- while (numLostBytes > 0) {
- size_t bufferSize = numLostBytes;
- if (numLostBytes > kMaxBufferSize) {
- numLostBytes -= kMaxBufferSize;
- bufferSize = kMaxBufferSize;
- } else {
- numLostBytes = 0;
- }
- MediaBuffer *lostAudioBuffer = new MediaBuffer(bufferSize);
- memset(lostAudioBuffer->data(), 0, bufferSize);
- lostAudioBuffer->set_range(0, bufferSize);
- queueInputBuffer_l(lostAudioBuffer, timeUs);
- }
-
- if (audioBuffer.size == 0) {
- ALOGW("Nothing is available from AudioRecord callback buffer");
- return OK;
- }
-
- const size_t bufferSize = audioBuffer.size;
- MediaBuffer *buffer = new MediaBuffer(bufferSize);
- memcpy((uint8_t *) buffer->data(),
- audioBuffer.i16, audioBuffer.size);
- buffer->set_range(0, bufferSize);
- queueInputBuffer_l(buffer, timeUs);
- return OK;
-}
-
-void AudioSource::queueInputBuffer_l(MediaBuffer *buffer, int64_t timeUs) {
- const size_t bufferSize = buffer->range_length();
- const size_t frameSize = mRecord->frameSize();
- const int64_t timestampUs =
- mPrevSampleTimeUs +
- ((1000000LL * (bufferSize / frameSize)) +
- (mSampleRate >> 1)) / mSampleRate;
-
- if (mNumFramesReceived == 0) {
- buffer->meta_data()->setInt64(kKeyAnchorTime, mStartTimeUs);
- }
-
- buffer->meta_data()->setInt64(kKeyTime, mPrevSampleTimeUs);
- buffer->meta_data()->setInt64(kKeyDriftTime, timeUs - mInitialReadTimeUs);
- mPrevSampleTimeUs = timestampUs;
- mNumFramesReceived += bufferSize / frameSize;
- mBuffersReceived.push_back(buffer);
- mFrameAvailableCondition.signal();
-}
-
-void AudioSource::trackMaxAmplitude(int16_t *data, int nSamples) {
- for (int i = nSamples; i > 0; --i) {
- int16_t value = *data++;
- if (value < 0) {
- value = -value;
- }
- if (mMaxAmplitude < value) {
- mMaxAmplitude = value;
- }
- }
-}
-
-int16_t AudioSource::getMaxAmplitude() {
- // First call activates the tracking.
- if (!mTrackMaxAmplitude) {
- mTrackMaxAmplitude = true;
- }
- int16_t value = mMaxAmplitude;
- mMaxAmplitude = 0;
- ALOGV("max amplitude since last call: %d", value);
- return value;
-}
-
-} // namespace android