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