AudioSource.cpp revision be6ec71af2d12e2a55f2f0b1b77d3fa5d593a1c7
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (C) 2010 The Android Open Source Project
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * you may not use this file except in compliance with the License.
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * You may obtain a copy of the License at
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * See the License for the specific language governing permissions and
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * limitations under the License.
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project//#define LOG_NDEBUG 0
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define LOG_TAG "AudioSource"
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <utils/Log.h>
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <media/stagefright/AudioSource.h>
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <media/AudioRecord.h>
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <media/stagefright/MediaBufferGroup.h>
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <media/stagefright/MediaDebug.h>
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <media/stagefright/MediaDefs.h>
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <media/stagefright/MetaData.h>
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <cutils/properties.h>
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/time.h>
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <time.h>
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectnamespace android {
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectAudioSource::AudioSource(
35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int inputSource, uint32_t sampleRate, uint32_t channels)
36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    : mStarted(false),
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project      mCollectStats(false),
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project      mTotalReadTimeUs(0),
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project      mTotalReadBytes(0),
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project      mTotalReads(0),
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project      mGroup(NULL) {
42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    LOGV("sampleRate: %d, channels: %d", sampleRate, channels);
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint32_t flags = AudioRecord::RECORD_AGC_ENABLE |
45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                     AudioRecord::RECORD_NS_ENABLE  |
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                     AudioRecord::RECORD_IIR_ENABLE;
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mRecord = new AudioRecord(
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                inputSource, sampleRate, AudioSystem::PCM_16_BIT,
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                channels > 1? AudioSystem::CHANNEL_IN_STEREO: AudioSystem::CHANNEL_IN_MONO,
516e1f21584f43311f35ae7f6a4737c6a7e846083aSan Mehat                4 * kMaxBufferSize / sizeof(int16_t), /* Enable ping-pong buffers */
524a6f2321e76685b9489d020980dffb1d9ac73fc0San Mehat                flags);
531f75d709c10f49d2e2390b888e766bcfd17da860Chung-yih Wang
5493ac1559b8c7ad3125ddcd896082b030faadbbd4Mike Lockwood    mInitCheck = mRecord->initCheck();
55e572d596b3715198fb48b3d8cef4939a71d58db2aimitakeshi}
561d91fcf7c0a31d27097b196579a37873ba1c0934Robert Greenwalt
57c29919c8d75ad218012daeda62e1e62200cad889Mike LockwoodAudioSource::~AudioSource() {
58a6a36c0b799b84d06b695027d205f21d13a3275bJeff Hamilton    if (mStarted) {
592e0047bdc067006d1e38418b2a0e24612d8068baMike Lockwood        stop();
60af7bdc646088e3112052f4fd35061bb720393287Mike Lockwood    }
61097b4ed4100369862793cf4f0fbbb969b50c154eNick Pelly
627005c0375416abb595721fe9c1324ed7356beb02Jeffrey Tinker    delete mRecord;
63097b4ed4100369862793cf4f0fbbb969b50c154eNick Pelly    mRecord = NULL;
6450458cf76ea7b0b03598c785acb1481ed0ae5b1dDianne Hackborn}
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatus_t AudioSource::initCheck() const {
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return mInitCheck;
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatus_t AudioSource::start(MetaData *params) {
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (mStarted) {
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return UNKNOWN_ERROR;
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
7688dc657d50cb3289a9011828c497eee996ed958cChia-chi Yeh    if (property_get("media.stagefright.record-stats", value, NULL)
774f1df18766fa13959f347f9c0cbb3dfa67273fa7Jeff Sharkey        && (!strcmp(value, "1") || !strcasecmp(value, "true"))) {
784f1df18766fa13959f347f9c0cbb3dfa67273fa7Jeff Sharkey        mCollectStats = true;
79971153aa4a65c4fbc8d916c619a17d3912b2cb02Matthew Xie    }
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    status_t err = mRecord->start();
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (err == OK) {
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        mGroup = new MediaBufferGroup;
84ca185abcb58582ab58805f792eb868681ebdb55eDianne Hackborn        mGroup->add_buffer(new MediaBuffer(kMaxBufferSize));
85ca185abcb58582ab58805f792eb868681ebdb55eDianne Hackborn
86ca185abcb58582ab58805f792eb868681ebdb55eDianne Hackborn        mStarted = true;
87ca185abcb58582ab58805f792eb868681ebdb55eDianne Hackborn    }
88ca185abcb58582ab58805f792eb868681ebdb55eDianne Hackborn
89ca185abcb58582ab58805f792eb868681ebdb55eDianne Hackborn    return err;
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
917e41c8420e015f6b96e35e90c8a9a8ebf643cdacKenny Root
927e41c8420e015f6b96e35e90c8a9a8ebf643cdacKenny Rootstatus_t AudioSource::stop() {
937e41c8420e015f6b96e35e90c8a9a8ebf643cdacKenny Root    if (!mStarted) {
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return UNKNOWN_ERROR;
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mRecord->stop();
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    delete mGroup;
1004688ac5b73abf15798415f7260f21bd87d23dd2bNick Kralevich    mGroup = NULL;
101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mStarted = false;
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (mCollectStats) {
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        LOGI("%lld reads: %.2f bps in %lld us",
106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                mTotalReads,
107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                (mTotalReadBytes * 8000000.0) / mTotalReadTimeUs,
108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                mTotalReadTimeUs);
109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return OK;
112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectsp<MetaData> AudioSource::getFormat() {
115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sp<MetaData> meta = new MetaData;
116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
117e572d596b3715198fb48b3d8cef4939a71d58db2aimitakeshi    meta->setInt32(kKeySampleRate, mRecord->getSampleRate());
1181d91fcf7c0a31d27097b196579a37873ba1c0934Robert Greenwalt    meta->setInt32(kKeyChannelCount, mRecord->channelCount());
11985905a6ab4d970f04d421bd2077ba4ad6fe67c3eNick Pelly    meta->setInt32(kKeyMaxInputSize, kMaxBufferSize);
1207005c0375416abb595721fe9c1324ed7356beb02Jeffrey Tinker
121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return meta;
122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatus_t AudioSource::read(
125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        MediaBuffer **out, const ReadOptions *options) {
126971153aa4a65c4fbc8d916c619a17d3912b2cb02Matthew Xie    *out = NULL;
1275d3aadbeca442b482a132371a46f3356489370b1Dianne Hackborn    ++mTotalReads;
1286e1f21584f43311f35ae7f6a4737c6a7e846083aSan Mehat
1292e0047bdc067006d1e38418b2a0e24612d8068baMike Lockwood    MediaBuffer *buffer;
1304a6f2321e76685b9489d020980dffb1d9ac73fc0San Mehat    CHECK_EQ(mGroup->acquire_buffer(&buffer), OK);
1311f75d709c10f49d2e2390b888e766bcfd17da860Chung-yih Wang
13293ac1559b8c7ad3125ddcd896082b030faadbbd4Mike Lockwood    uint32_t numFramesRecorded;
133af7bdc646088e3112052f4fd35061bb720393287Mike Lockwood    mRecord->getPosition(&numFramesRecorded);
134c29919c8d75ad218012daeda62e1e62200cad889Mike Lockwood    int64_t latency = mRecord->latency() * 1000;
1351f75d709c10f49d2e2390b888e766bcfd17da860Chung-yih Wang    uint32_t sampleRate = mRecord->getSampleRate();
136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int64_t timestampUs = (1000000LL * numFramesRecorded) / sampleRate - latency;
13788dc657d50cb3289a9011828c497eee996ed958cChia-chi Yeh    LOGV("latency: %lld, sample rate: %d, timestamp: %lld",
1384f1df18766fa13959f347f9c0cbb3dfa67273fa7Jeff Sharkey            latency, sampleRate, timestampUs);
1394f1df18766fa13959f347f9c0cbb3dfa67273fa7Jeff Sharkey
140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    buffer->meta_data()->setInt64(kKeyTime, timestampUs);
141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ssize_t n = 0;
143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (mCollectStats) {
144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        struct timeval tv_start, tv_end;
145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        gettimeofday(&tv_start, NULL);
14608c370cc50e4bdae5a59f4ddfd1e3874bb36579dDoug Zongker        n = mRecord->read(buffer->data(), buffer->size());
147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        gettimeofday(&tv_end, NULL);
148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        mTotalReadTimeUs += ((1000000LL * (tv_end.tv_sec - tv_start.tv_sec))
149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                + (tv_end.tv_usec - tv_start.tv_usec));
150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (n >= 0) {
151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            mTotalReadBytes += n;
152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        n = mRecord->read(buffer->data(), buffer->size());
155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (n < 0) {
158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        buffer->release();
159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        buffer = NULL;
160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return (status_t)n;
162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    buffer->set_range(0, n);
165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    *out = buffer;
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return OK;
169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1701ace223fcbf8da9e0d22e31c1b3129a7a8276cb1Paul Eastham
1711ace223fcbf8da9e0d22e31c1b3129a7a8276cb1Paul Eastham}  // namespace android
172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project