AudioRecord.cpp revision ad04d9201452001dbaac4349f084cc9316190b89
10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/* 20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville** 30825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville** Copyright 2008, The Android Open Source Project 40825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville** 50825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville** Licensed under the Apache License, Version 2.0 (the "License"); 60825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville** you may not use this file except in compliance with the License. 70825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville** You may obtain a copy of the License at 80825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville** 90825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville** http://www.apache.org/licenses/LICENSE-2.0 100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville** 110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville** Unless required by applicable law or agreed to in writing, software 120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville** distributed under the License is distributed on an "AS IS" BASIS, 130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville** See the License for the specific language governing permissions and 150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville** limitations under the License. 160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville*/ 170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville//#define LOG_NDEBUG 0 190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville#define LOG_TAG "AudioRecord" 200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville#include <stdint.h> 220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville#include <sys/types.h> 230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville#include <sched.h> 250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville#include <sys/resource.h> 260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville#include <private/media/AudioTrackShared.h> 280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville#include <media/AudioSystem.h> 300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville#include <media/AudioRecord.h> 310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville#include <utils/IServiceManager.h> 33e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka#include <utils/Log.h> 34e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka#include <utils/MemoryDealer.h> 350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville#include <utils/Parcel.h> 360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville#include <utils/IPCThreadState.h> 370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville#include <utils/Timers.h> 380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville#include <cutils/atomic.h> 390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true )) 410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false )) 420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 430825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillenamespace android { 440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville// --------------------------------------------------------------------------- 460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 470825495a331bb44df395a0cdb79fab85e68db5d5Wink SavilleAudioRecord::AudioRecord() 480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville : mStatus(NO_INIT) 490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 520825495a331bb44df395a0cdb79fab85e68db5d5Wink SavilleAudioRecord::AudioRecord( 530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int streamType, 540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville uint32_t sampleRate, 550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int format, 560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int channelCount, 570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int frameCount, 580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville uint32_t flags, 590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville callback_t cbf, 600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville void* user, 610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int notificationFrames) 620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville : mStatus(NO_INIT) 630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mStatus = set(streamType, sampleRate, format, channelCount, 650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville frameCount, flags, cbf, user, notificationFrames); 660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 68e287feac673ff68565b766e0e463d105fa9cef9dAlex YakavenkaAudioRecord::~AudioRecord() 690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mStatus == NO_ERROR) { 710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Make sure that callback function exits in the case where 720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // it is looping on buffer empty condition in obtainBuffer(). 730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Otherwise the callback thread will never exit. 740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville stop(); 750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mClientRecordThread != 0) { 760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCblk->cv.signal(); 770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mClientRecordThread->requestExitAndWait(); 780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mClientRecordThread.clear(); 790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mAudioRecord.clear(); 810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville IPCThreadState::self()->flushCommands(); 820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 850825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillestatus_t AudioRecord::set( 860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int streamType, 870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville uint32_t sampleRate, 880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int format, 890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int channelCount, 900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int frameCount, 910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville uint32_t flags, 920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville callback_t cbf, 930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville void* user, 940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int notificationFrames, 950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville bool threadCanCallJava) 960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville LOGV("set(): sampleRate %d, channelCount %d, frameCount %d",sampleRate, channelCount, frameCount); 990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mAudioFlinger != 0) { 1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return INVALID_OPERATION; 1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); 1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (audioFlinger == 0) { 1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return NO_INIT; 106e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka } 107e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 108e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (streamType == DEFAULT_INPUT) { 1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville streamType = MIC_INPUT; 1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (sampleRate == 0) { 1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sampleRate = DEFAULT_SAMPLE_RATE; 1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // these below should probably come from the audioFlinger too... 1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (format == 0) { 1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville format = AudioSystem::PCM_16_BIT; 1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (channelCount == 0) { 1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville channelCount = 1; 1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // validate parameters 1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (format != AudioSystem::PCM_16_BIT) { 1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return BAD_VALUE; 1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 127e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka if (channelCount != 1 && channelCount != 2) { 1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return BAD_VALUE; 1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 130e287feac673ff68565b766e0e463d105fa9cef9dAlex Yakavenka 1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // TODO: Get input frame count from hardware. 1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int minFrameCount = 1024*2; 1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (frameCount == 0) { 1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville frameCount = minFrameCount; 1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if (frameCount < minFrameCount) { 1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return BAD_VALUE; 1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (notificationFrames == 0) { 1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville notificationFrames = frameCount/2; 1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // open record channel 1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville status_t status; 1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), streamType, 1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sampleRate, format, channelCount, frameCount, flags, &status); 1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (record == 0) { 1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville LOGE("AudioFlinger could not create record track, status: %d", status); 1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return status; 1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sp<IMemory> cblk = record->getCblk(); 1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (cblk == 0) { 1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return NO_INIT; 1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (cbf != 0) { 1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mClientRecordThread = new ClientRecordThread(*this, threadCanCallJava); 1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mClientRecordThread == 0) { 1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return NO_INIT; 1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mStatus = NO_ERROR; 1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mAudioFlinger = audioFlinger; 1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mAudioRecord = record; 1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCblkMemory = cblk; 1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer()); 1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t); 1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCblk->out = 0; 1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mSampleRate = sampleRate; 1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mFormat = format; 1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Update buffer size in case it has been limited by AudioFlinger during track creation 1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mFrameCount = mCblk->frameCount; 1751e5f46c0477703b0eef40278cfa101d20b53091aJohn Wang mChannelCount = channelCount; 1769fdeecb4aa06552efcc535f21718cae45cc604e2Wink Saville mActive = 0; 1771e5f46c0477703b0eef40278cfa101d20b53091aJohn Wang mCbf = cbf; 1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mNotificationFrames = notificationFrames; 1791e5f46c0477703b0eef40278cfa101d20b53091aJohn Wang mRemainingFrames = notificationFrames; 1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mUserData = user; 1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // TODO: add audio hardware input latency here 1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mLatency = (1000*mFrameCount) / mSampleRate; 1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mMarkerPosition = 0; 1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mNewPosition = 0; 1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mUpdatePeriod = 0; 1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return NO_ERROR; 1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillestatus_t AudioRecord::initCheck() const 1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mStatus; 1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville// ------------------------------------------------------------------------- 1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleuint32_t AudioRecord::latency() const 1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mLatency; 2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleuint32_t AudioRecord::sampleRate() const 2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mSampleRate; 2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleint AudioRecord::format() const 2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mFormat; 2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleint AudioRecord::channelCount() const 2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mChannelCount; 2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleuint32_t AudioRecord::frameCount() const 2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mFrameCount; 2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleint AudioRecord::frameSize() const 2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return channelCount()*((format() == AudioSystem::PCM_8_BIT) ? sizeof(uint8_t) : sizeof(int16_t)); 2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville// ------------------------------------------------------------------------- 2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillestatus_t AudioRecord::start() 2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville status_t ret = NO_ERROR; 2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sp<ClientRecordThread> t = mClientRecordThread; 2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville LOGV("start"); 2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (t != 0) { 2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (t->exitPending()) { 2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (t->requestExitAndWait() == WOULD_BLOCK) { 2390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville LOGE("AudioRecord::start called from thread"); 2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return WOULD_BLOCK; 2410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville t->mLock.lock(); 2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (android_atomic_or(1, &mActive) == 0) { 2470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mNewPosition = mCblk->user + mUpdatePeriod; 2480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; 2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCblk->waitTimeMs = 0; 2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (t != 0) { 2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville t->run("ClientRecordThread", THREAD_PRIORITY_AUDIO_CLIENT); 2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT); 2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ret = mAudioRecord->start(); 2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (t != 0) { 2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville t->mLock.unlock(); 2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return ret; 2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillestatus_t AudioRecord::stop() 2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville sp<ClientRecordThread> t = mClientRecordThread; 2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville LOGV("stop"); 2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (t != 0) { 2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville t->mLock.lock(); 2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (android_atomic_and(~1, &mActive) == 1) { 2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mAudioRecord->stop(); 2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (t != 0) { 2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville t->requestExit(); 2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL); 2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (t != 0) { 2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville t->mLock.unlock(); 2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return NO_ERROR; 2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillebool AudioRecord::stopped() const 2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return !mActive; 2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillestatus_t AudioRecord::setMarkerPosition(uint32_t marker) 2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mCbf == 0) return INVALID_OPERATION; 2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mMarkerPosition = marker; 3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return NO_ERROR; 3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillestatus_t AudioRecord::getMarkerPosition(uint32_t *marker) 3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (marker == 0) return BAD_VALUE; 3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *marker = mMarkerPosition; 3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return NO_ERROR; 3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillestatus_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod) 3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mCbf == 0) return INVALID_OPERATION; 3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville uint32_t curPosition; 3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville getPosition(&curPosition); 3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mNewPosition = curPosition + updatePeriod; 3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mUpdatePeriod = updatePeriod; 3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return NO_ERROR; 3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillestatus_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod) 3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (updatePeriod == 0) return BAD_VALUE; 3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *updatePeriod = mUpdatePeriod; 3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return NO_ERROR; 3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillestatus_t AudioRecord::getPosition(uint32_t *position) 3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (position == 0) return BAD_VALUE; 3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *position = mCblk->user; 3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return NO_ERROR; 3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville// ------------------------------------------------------------------------- 3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillestatus_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) 3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int active; 3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int timeout = 0; 3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville status_t result; 3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville audio_track_cblk_t* cblk = mCblk; 3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville uint32_t framesReq = audioBuffer->frameCount; 3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville audioBuffer->frameCount = 0; 3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville audioBuffer->size = 0; 3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville uint32_t framesReady = cblk->framesReady(); 3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (framesReady == 0) { 3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Mutex::Autolock _l(cblk->lock); 3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville goto start_loop_here; 3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville while (framesReady == 0) { 3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville active = mActive; 3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (UNLIKELY(!active)) 3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return NO_MORE_BUFFERS; 3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (UNLIKELY(!waitCount)) 3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return WOULD_BLOCK; 3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville timeout = 0; 3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville result = cblk->cv.waitRelative(cblk->lock, milliseconds(WAIT_PERIOD_MS)); 3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (__builtin_expect(result!=NO_ERROR, false)) { 3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cblk->waitTimeMs += WAIT_PERIOD_MS; 3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) { 3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville LOGW( "obtainBuffer timed out (is the CPU pegged?) " 3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "user=%08x, server=%08x", cblk->user, cblk->server); 3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville timeout = 1; 3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cblk->waitTimeMs = 0; 3780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (--waitCount == 0) { 3800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return TIMED_OUT; 3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // read the server count again 3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville start_loop_here: 3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville framesReady = cblk->framesReady(); 3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville LOGW_IF(timeout, 3900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "*** SERIOUS WARNING *** obtainBuffer() timed out " 3910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "but didn't need to be locked. We recovered, but " 3920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville "this shouldn't happen (user=%08x, server=%08x)", cblk->user, cblk->server); 3930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cblk->waitTimeMs = 0; 3950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (framesReq > framesReady) { 3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville framesReq = framesReady; 3980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville uint32_t u = cblk->user; 4010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville uint32_t bufferEnd = cblk->userBase + cblk->frameCount; 4020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (u + framesReq > bufferEnd) { 4040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville framesReq = bufferEnd - u; 4050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville audioBuffer->flags = 0; 4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville audioBuffer->channelCount= mChannelCount; 4090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville audioBuffer->format = mFormat; 4100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville audioBuffer->frameCount = framesReq; 4110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville audioBuffer->size = framesReq*mChannelCount*sizeof(int16_t); 4120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville audioBuffer->raw = (int8_t*)cblk->buffer(u); 4130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville active = mActive; 4140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return active ? status_t(NO_ERROR) : status_t(STOPPED); 4150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 4160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4170825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillevoid AudioRecord::releaseBuffer(Buffer* audioBuffer) 4180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 4190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville audio_track_cblk_t* cblk = mCblk; 4200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville cblk->stepUser(audioBuffer->frameCount); 4210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 4220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville// ------------------------------------------------------------------------- 4240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4250825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillessize_t AudioRecord::read(void* buffer, size_t userSize) 4260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 4270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ssize_t read = 0; 4280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Buffer audioBuffer; 4290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int8_t *dst = static_cast<int8_t*>(buffer); 4300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (ssize_t(userSize) < 0) { 4320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // sanity-check. user is most-likely passing an error code. 4330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville LOGE("AudioRecord::read(buffer=%p, size=%u (%d)", 4340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville buffer, userSize, userSize); 4350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return BAD_VALUE; 4360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville LOGV("read size: %d", userSize); 4390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville do { 4410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville audioBuffer.frameCount = userSize/mChannelCount/sizeof(int16_t); 4430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Calling obtainBuffer() with a negative wait count causes 4450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // an (almost) infinite wait time. 4460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville status_t err = obtainBuffer(&audioBuffer, -1); 4470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (err < 0) { 4480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // out of buffers, return #bytes written 4490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (err == status_t(NO_MORE_BUFFERS)) 4500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 4510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return ssize_t(err); 4520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville size_t bytesRead = audioBuffer.size; 4550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville memcpy(dst, audioBuffer.i8, bytesRead); 4560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville dst += bytesRead; 4580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville userSize -= bytesRead; 4590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville read += bytesRead; 4600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville releaseBuffer(&audioBuffer); 4620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } while (userSize); 4630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return read; 4650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 4660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville// ------------------------------------------------------------------------- 4680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4690825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillebool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread) 4700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 4710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Buffer audioBuffer; 4720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville uint32_t frames = mRemainingFrames; 4730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville size_t readSize; 4740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Manage marker callback 4760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mMarkerPosition > 0) { 4770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mCblk->user >= mMarkerPosition) { 4780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCbf(EVENT_MARKER, mUserData, (void *)&mMarkerPosition); 4790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mMarkerPosition = 0; 4800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Manage new position callback 4840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mUpdatePeriod > 0) { 4850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville while (mCblk->user >= mNewPosition) { 4860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCbf(EVENT_NEW_POS, mUserData, (void *)&mNewPosition); 4870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mNewPosition += mUpdatePeriod; 4880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville do { 4920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville audioBuffer.frameCount = frames; 4930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Calling obtainBuffer() with a wait count of 1 4940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // limits wait time to WAIT_PERIOD_MS. This prevents from being 4950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // stuck here not being able to handle timed events (position, markers). 4960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville status_t err = obtainBuffer(&audioBuffer, 1); 4970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (err < NO_ERROR) { 4980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (err != TIMED_OUT) { 4990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville LOGE("Error obtaining an audio buffer, giving up."); 5000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return false; 5010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville break; 5030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (err == status_t(STOPPED)) return false; 5050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville size_t reqSize = audioBuffer.size; 5070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer); 5080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville readSize = audioBuffer.size; 5090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Sanity check on returned size 5110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (ssize_t(readSize) <= 0) break; 5120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (readSize > reqSize) readSize = reqSize; 5130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville audioBuffer.size = readSize; 5150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville audioBuffer.frameCount = readSize/mChannelCount/sizeof(int16_t); 5160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville frames -= audioBuffer.frameCount; 5170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville releaseBuffer(&audioBuffer); 5190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } while (frames); 5210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Manage overrun callback 5240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mActive && (mCblk->framesAvailable_l() == 0)) { 5250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville LOGV("Overrun user: %x, server: %x, flowControlFlag %d", mCblk->user, mCblk->server, mCblk->flowControlFlag); 5260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mCblk->flowControlFlag == 0) { 5270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCbf(EVENT_OVERRUN, mUserData, 0); 5280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mCblk->flowControlFlag = 1; 5290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (frames == 0) { 5330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mRemainingFrames = mNotificationFrames; 5340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 5350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mRemainingFrames = frames; 5360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 5370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return true; 5380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 5390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville// ========================================================================= 5410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5420825495a331bb44df395a0cdb79fab85e68db5d5Wink SavilleAudioRecord::ClientRecordThread::ClientRecordThread(AudioRecord& receiver, bool bCanCallJava) 5430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville : Thread(bCanCallJava), mReceiver(receiver) 5440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 5450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 5460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5470825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillebool AudioRecord::ClientRecordThread::threadLoop() 5480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{ 5490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mReceiver.processAudioBuffer(this); 5500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 5510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville// ------------------------------------------------------------------------- 5530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}; // namespace android 5550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 5560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville