AudioRecord.cpp revision 2986460984580833161bdaabc7f17da1005a8961
189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project/*
289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project**
389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** Copyright 2008, The Android Open Source Project
489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project**
589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** you may not use this file except in compliance with the License.
789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** You may obtain a copy of the License at
889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project**
989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
1089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project**
1189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
1289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
1389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** See the License for the specific language governing permissions and
1589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** limitations under the License.
1689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project*/
1789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
1889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//#define LOG_NDEBUG 0
1989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#define LOG_TAG "AudioRecord"
2089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
2189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <stdint.h>
2289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <sys/types.h>
2389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
2489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <sched.h>
2589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <sys/resource.h>
2689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
2789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <private/media/AudioTrackShared.h>
2889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
2989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <media/AudioSystem.h>
3089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <media/AudioRecord.h>
31c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent#include <media/mediarecorder.h>
3289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
337562408b2261d38415453378b6188f74fda99d88Mathias Agopian#include <binder/IServiceManager.h>
3489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <utils/Log.h>
357562408b2261d38415453378b6188f74fda99d88Mathias Agopian#include <binder/Parcel.h>
367562408b2261d38415453378b6188f74fda99d88Mathias Agopian#include <binder/IPCThreadState.h>
3789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <utils/Timers.h>
3838ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent#include <utils/Atomic.h>
3989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
4064760240f931714858a59c1579f07264d7182ba2Dima Zavin#include <system/audio.h>
41fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin#include <cutils/bitops.h>
42f6b1678f8f508b447155a81b44e214475ab634a8Glenn Kasten#include <cutils/compiler.h>
4389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
4489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectnamespace android {
4515304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh// ---------------------------------------------------------------------------
4615304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh
4715304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh// static
4815304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yehstatus_t AudioRecord::getMinFrameCount(
4915304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh        int* frameCount,
5015304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh        uint32_t sampleRate,
5158f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten        audio_format_t format,
5215304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh        int channelCount)
5315304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh{
5415304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    size_t size = 0;
5515304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    if (AudioSystem::getInputBufferSize(sampleRate, format, channelCount, &size)
5615304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh            != NO_ERROR) {
5729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("AudioSystem could not query the input buffer size.");
5815304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh        return NO_INIT;
5915304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    }
6015304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh
6115304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    if (size == 0) {
6229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Unsupported configuration: sampleRate %d, format %d, channelCount %d",
6315304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh            sampleRate, format, channelCount);
6415304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh        return BAD_VALUE;
6515304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    }
6615304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh
6715304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    // We double the size of input buffer for ping pong use of record buffer.
6815304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    size <<= 1;
6915304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh
70fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (audio_is_linear_pcm(format)) {
71671a636931295d9c33ffca74551a804479d01241Eric Laurent        size /= channelCount * audio_bytes_per_sample(format);
7215304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    }
7315304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh
7415304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    *frameCount = size;
7515304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    return NO_ERROR;
7615304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh}
7789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
7889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ---------------------------------------------------------------------------
7989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
8089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::AudioRecord()
81879135196fd1c97deefc538c888037c56c2879a7Glenn Kasten    : mStatus(NO_INIT), mSessionId(0),
82a636433cbd09c0708b85f337ef45c0cdef3bcb4dGlenn Kasten      mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT)
8389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
8489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
8589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
8689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::AudioRecord(
87eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kasten        audio_source_t inputSource,
8889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        uint32_t sampleRate,
8958f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten        audio_format_t format,
900d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi        uint32_t channelMask,
9189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int frameCount,
92679ab0b0792846a89162ce41c953819d70030112Glenn Kasten        record_flags flags,
9389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        callback_t cbf,
9489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        void* user,
95be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        int notificationFrames,
96be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        int sessionId)
97879135196fd1c97deefc538c888037c56c2879a7Glenn Kasten    : mStatus(NO_INIT), mSessionId(0),
98a636433cbd09c0708b85f337ef45c0cdef3bcb4dGlenn Kasten      mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT)
9989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
1000d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi    mStatus = set(inputSource, sampleRate, format, channelMask,
101be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent            frameCount, flags, cbf, user, notificationFrames, sessionId);
10289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
10389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
10489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::~AudioRecord()
10589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
10689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mStatus == NO_ERROR) {
10789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // Make sure that callback function exits in the case where
10889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // it is looping on buffer empty condition in obtainBuffer().
10989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // Otherwise the callback thread will never exit.
11089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        stop();
11189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (mClientRecordThread != 0) {
11289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mClientRecordThread->requestExitAndWait();
11389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mClientRecordThread.clear();
11489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
11589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mAudioRecord.clear();
11689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        IPCThreadState::self()->flushCommands();
1173a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        AudioSystem::releaseAudioSessionId(mSessionId);
11889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
11989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
12089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
12189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::set(
122eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kasten        audio_source_t inputSource,
12389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        uint32_t sampleRate,
12458f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten        audio_format_t format,
1250d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi        uint32_t channelMask,
12689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int frameCount,
127679ab0b0792846a89162ce41c953819d70030112Glenn Kasten        record_flags flags,
12889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        callback_t cbf,
12989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        void* user,
13089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int notificationFrames,
131be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        bool threadCanCallJava,
132be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        int sessionId)
13389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
13489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
1353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("set(): sampleRate %d, channelMask %d, frameCount %d",sampleRate, channelMask, frameCount);
1361703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
1371703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    AutoMutex lock(mLock);
1381703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
1391dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent    if (mAudioRecord != 0) {
14089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return INVALID_OPERATION;
14189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
14289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
143c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    if (inputSource == AUDIO_SOURCE_DEFAULT) {
144c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        inputSource = AUDIO_SOURCE_MIC;
14589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
14689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
14789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (sampleRate == 0) {
14889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        sampleRate = DEFAULT_SAMPLE_RATE;
14989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
15089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // these below should probably come from the audioFlinger too...
15158f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten    if (format == AUDIO_FORMAT_DEFAULT) {
152fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        format = AUDIO_FORMAT_PCM_16_BIT;
15389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
154c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    // validate parameters
155fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (!audio_is_valid_format(format)) {
15629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Invalid format");
157c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        return BAD_VALUE;
15889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
15989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
1600d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi    if (!audio_is_input_channel(channelMask)) {
16189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return BAD_VALUE;
16289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
163be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent
1640d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi    int channelCount = popcount(channelMask);
165c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent
1667c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (sessionId == 0 ) {
1677c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        mSessionId = AudioSystem::newAudioSessionId();
1687c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    } else {
1697c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        mSessionId = sessionId;
1707c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
1713856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("set(): mSessionId %d", mSessionId);
1727c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
1736100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent    audio_io_handle_t input = AudioSystem::getInput(inputSource,
1747c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                                    sampleRate,
1757c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                                    format,
1767c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                                    channelMask,
1777c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                                    (audio_in_acoustics_t)flags,
1787c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                                    mSessionId);
1796100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent    if (input == 0) {
18029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Could not get audio input for record source %d", inputSource);
18189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return BAD_VALUE;
18289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
18389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
18489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // validate framecount
18515304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    int minFrameCount = 0;
18615304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    status_t status = getMinFrameCount(&minFrameCount, sampleRate, format, channelCount);
18715304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    if (status != NO_ERROR) {
18815304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh        return status;
189c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    }
1903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioRecord::set() minFrameCount = %d", minFrameCount);
19189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
19289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (frameCount == 0) {
19389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        frameCount = minFrameCount;
19489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } else if (frameCount < minFrameCount) {
19589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return BAD_VALUE;
19689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
19789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
19889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (notificationFrames == 0) {
19989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        notificationFrames = frameCount/2;
20089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
20189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
20234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    // create the IAudioRecord
2030d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi    status = openRecord_l(sampleRate, format, channelMask,
204a075db4ff9b086ac2885df77bb6da0869293df92Glenn Kasten                        frameCount, input);
20534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    if (status != NO_ERROR) {
20689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return status;
20789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
20834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent
209a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten    if (cbf != NULL) {
21089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mClientRecordThread = new ClientRecordThread(*this, threadCanCallJava);
21189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
21289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
21389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mStatus = NO_ERROR;
21489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
21589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mFormat = format;
21689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // Update buffer size in case it has been limited by AudioFlinger during track creation
21789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mFrameCount = mCblk->frameCount;
218c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    mChannelCount = (uint8_t)channelCount;
2190d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi    mChannelMask = channelMask;
22089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mActive = 0;
22189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mCbf = cbf;
22289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mNotificationFrames = notificationFrames;
22389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mRemainingFrames = notificationFrames;
22489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mUserData = user;
22589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // TODO: add audio hardware input latency here
226573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent    mLatency = (1000*mFrameCount) / sampleRate;
22789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mMarkerPosition = 0;
2287d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi    mMarkerReached = false;
22989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mNewPosition = 0;
23089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mUpdatePeriod = 0;
231eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kasten    mInputSource = inputSource;
23234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    mFlags = flags;
23305bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent    mInput = input;
2343a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    AudioSystem::acquireAudioSessionId(mSessionId);
23589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
23689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
23789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
23889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
23989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::initCheck() const
24089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
24189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mStatus;
24289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
24389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
24489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// -------------------------------------------------------------------------
24589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
24689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectuint32_t AudioRecord::latency() const
24789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
24889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mLatency;
24989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
25089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
25158f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kastenaudio_format_t AudioRecord::format() const
25289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
25389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mFormat;
25489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
25589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
25689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint AudioRecord::channelCount() const
25789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
25889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mChannelCount;
25989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
26089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
26189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectuint32_t AudioRecord::frameCount() const
26289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
26389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mFrameCount;
26489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
26589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
266b9980659501d0428d65d8292f3c32da69d37fbd2Glenn Kastensize_t AudioRecord::frameSize() const
26789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
268fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (audio_is_linear_pcm(mFormat)) {
269671a636931295d9c33ffca74551a804479d01241Eric Laurent        return channelCount()*audio_bytes_per_sample(mFormat);
270c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    } else {
271c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        return sizeof(uint8_t);
272c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    }
27389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
27489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
275eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kastenaudio_source_t AudioRecord::inputSource() const
276f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent{
277eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kasten    return mInputSource;
278f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent}
279f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent
28089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// -------------------------------------------------------------------------
28189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
282a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurentstatus_t AudioRecord::start(AudioSystem::sync_event_t event, int triggerSession)
28389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
28489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    status_t ret = NO_ERROR;
28589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<ClientRecordThread> t = mClientRecordThread;
28689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
287a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    ALOGV("start, sync event %d trigger session %d", event, triggerSession);
28889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
28989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (t != 0) {
29089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (t->exitPending()) {
29189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            if (t->requestExitAndWait() == WOULD_BLOCK) {
29229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                ALOGE("AudioRecord::start called from thread");
29389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                return WOULD_BLOCK;
29489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            }
29589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
296e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    }
29789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
298f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent    AutoMutex lock(mLock);
2991703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed
3001703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    // while we are accessing the cblk
301e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    sp<IAudioRecord> audioRecord = mAudioRecord;
302e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    sp<IMemory> iMem = mCblkMemory;
3031703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    audio_track_cblk_t* cblk = mCblk;
304f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent    if (mActive == 0) {
305f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent        mActive = 1;
3061703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
3076dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten        pid_t tid;
3086dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten        if (t != 0) {
3096dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten            mReadyToRun = WOULD_BLOCK;
310480b46802bef1371d5caa16ad5454fce04769c57Glenn Kasten            t->run("AudioRecord", ANDROID_PRIORITY_AUDIO);
3116dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten            tid = t->getTid();  // pid_t is unknown until run()
3126dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten            ALOGV("getTid=%d", tid);
3136dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten            if (tid == -1) {
3146dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten                tid = 0;
3156dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten            }
3166dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten            // thread blocks in readyToRun()
3176dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten        } else {
3186dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten            tid = 0;    // not gettid()
3196dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten        }
3206dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten
3211703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        cblk->lock.lock();
3221703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        if (!(cblk->flags & CBLK_INVALID_MSK)) {
3231703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            cblk->lock.unlock();
3243acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten            ALOGV("mAudioRecord->start()");
3253acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten            ret = mAudioRecord->start(event, triggerSession);
3261703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            cblk->lock.lock();
3271703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            if (ret == DEAD_OBJECT) {
32838ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent                android_atomic_or(CBLK_INVALID_ON, &cblk->flags);
3296100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent            }
3306100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent        }
3311703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        if (cblk->flags & CBLK_INVALID_MSK) {
3321703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            ret = restoreRecord_l(cblk);
3331703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        }
3341703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        cblk->lock.unlock();
3356100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent        if (ret == NO_ERROR) {
3361703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            mNewPosition = cblk->user + mUpdatePeriod;
3372986460984580833161bdaabc7f17da1005a8961Eric Laurent            cblk->bufferTimeoutMs = (event == AudioSystem::SYNC_EVENT_NONE) ? MAX_RUN_TIMEOUT_MS :
3382986460984580833161bdaabc7f17da1005a8961Eric Laurent                                            AudioSystem::kSyncRecordStartTimeOutMs;
3391703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            cblk->waitTimeMs = 0;
3406100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent            if (t != 0) {
3416dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten                // thread unblocks in readyToRun() and returns NO_ERROR
3426dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten                mReadyToRun = NO_ERROR;
3436dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten                mCondition.signal();
344c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent            } else {
345879135196fd1c97deefc538c888037c56c2879a7Glenn Kasten                mPreviousPriority = getpriority(PRIO_PROCESS, 0);
346a636433cbd09c0708b85f337ef45c0cdef3bcb4dGlenn Kasten                get_sched_policy(0, &mPreviousSchedulingGroup);
347879135196fd1c97deefc538c888037c56c2879a7Glenn Kasten                androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO);
348c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent            }
3496100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent        } else {
350f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent            mActive = 0;
3516dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten            // thread unblocks in readyToRun() and returns NO_INIT
3526dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten            mReadyToRun = NO_INIT;
3536dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten            mCondition.signal();
35489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
35589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
35689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
35789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return ret;
35889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
35989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
36089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::stop()
36189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
36289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<ClientRecordThread> t = mClientRecordThread;
36389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
3643856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("stop");
36589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
366f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent    AutoMutex lock(mLock);
367f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent    if (mActive == 1) {
368f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent        mActive = 0;
3691dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent        mCblk->cv.signal();
37089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mAudioRecord->stop();
3717d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi        // the record head position will reset to 0, so if a marker is set, we need
3727d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi        // to activate it again
3737d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi        mMarkerReached = false;
37489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (t != 0) {
37589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            t->requestExit();
37689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        } else {
377879135196fd1c97deefc538c888037c56c2879a7Glenn Kasten            setpriority(PRIO_PROCESS, 0, mPreviousPriority);
378a636433cbd09c0708b85f337ef45c0cdef3bcb4dGlenn Kasten            set_sched_policy(0, mPreviousSchedulingGroup);
37989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
38089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
38189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
38289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
38389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
38489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
38589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool AudioRecord::stopped() const
38689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
38789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return !mActive;
38889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
38989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
390606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenuint32_t AudioRecord::getSampleRate() const
391573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent{
3921703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    AutoMutex lock(mLock);
393573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent    return mCblk->sampleRate;
394573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent}
395573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent
39689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::setMarkerPosition(uint32_t marker)
39789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
398a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten    if (mCbf == NULL) return INVALID_OPERATION;
39989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
40089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mMarkerPosition = marker;
4017d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi    mMarkerReached = false;
40289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
40389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
40489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
40589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
406606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenstatus_t AudioRecord::getMarkerPosition(uint32_t *marker) const
40789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
408a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten    if (marker == NULL) return BAD_VALUE;
40989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
41089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *marker = mMarkerPosition;
41189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
41289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
41389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
41489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
41589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod)
41689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
417a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten    if (mCbf == NULL) return INVALID_OPERATION;
41889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
41989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t curPosition;
42089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    getPosition(&curPosition);
42189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mNewPosition = curPosition + updatePeriod;
42289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mUpdatePeriod = updatePeriod;
42389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
42489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
42589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
42689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
427606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenstatus_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod) const
42889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
429a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten    if (updatePeriod == NULL) return BAD_VALUE;
43089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
43189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *updatePeriod = mUpdatePeriod;
43289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
43389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
43489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
43589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
436606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenstatus_t AudioRecord::getPosition(uint32_t *position) const
43789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
438a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten    if (position == NULL) return BAD_VALUE;
43989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
4401703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    AutoMutex lock(mLock);
44189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *position = mCblk->user;
44289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
44389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
44489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
44589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
446606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenunsigned int AudioRecord::getInputFramesLost() const
44705bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent{
44805bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent    if (mActive)
44905bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent        return AudioSystem::getInputFramesLost(mInput);
45005bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent    else
45105bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent        return 0;
45205bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent}
45389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
45489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// -------------------------------------------------------------------------
45589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
4561703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// must be called with mLock held
4571703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurentstatus_t AudioRecord::openRecord_l(
45834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        uint32_t sampleRate,
45958f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten        audio_format_t format,
4600d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi        uint32_t channelMask,
46134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        int frameCount,
4626100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent        audio_io_handle_t input)
46334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent{
46434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    status_t status;
46534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
46634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    if (audioFlinger == 0) {
46734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        return NO_INIT;
46834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    }
46934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent
4706100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent    sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), input,
47134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                                                       sampleRate, format,
4720d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi                                                       channelMask,
47334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                                                       frameCount,
474a075db4ff9b086ac2885df77bb6da0869293df92Glenn Kasten                                                       IAudioFlinger::TRACK_DEFAULT,
475be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent                                                       &mSessionId,
47634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                                                       &status);
4773a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen
47834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    if (record == 0) {
47929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("AudioFlinger could not create record track, status: %d", status);
48034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        return status;
48134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    }
48234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    sp<IMemory> cblk = record->getCblk();
48334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    if (cblk == 0) {
48429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Could not get control block");
48534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        return NO_INIT;
48634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    }
48734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    mAudioRecord.clear();
48834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    mAudioRecord = record;
48934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    mCblkMemory.clear();
49034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    mCblkMemory = cblk;
49134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
49234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
49338ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent    android_atomic_and(~CBLK_DIRECTION_MSK, &mCblk->flags);
4946100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent    mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
4956100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent    mCblk->waitTimeMs = 0;
49634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    return NO_ERROR;
49734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent}
49834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent
49989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
50089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
5011703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    AutoMutex lock(mLock);
50289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    int active;
503d0965dde97f2815ae0a15fe6b40946f8a741a81eGlenn Kasten    status_t result = NO_ERROR;
50489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audio_track_cblk_t* cblk = mCblk;
50589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t framesReq = audioBuffer->frameCount;
5061dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent    uint32_t waitTimeMs = (waitCount < 0) ? cblk->bufferTimeoutMs : WAIT_PERIOD_MS;
50789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
50889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->frameCount  = 0;
50989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->size        = 0;
51089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
51189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t framesReady = cblk->framesReady();
51289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
51389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (framesReady == 0) {
51434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        cblk->lock.lock();
51589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        goto start_loop_here;
51689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        while (framesReady == 0) {
51789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            active = mActive;
518f6b1678f8f508b447155a81b44e214475ab634a8Glenn Kasten            if (CC_UNLIKELY(!active)) {
51934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                cblk->lock.unlock();
52089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                return NO_MORE_BUFFERS;
52134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent            }
522f6b1678f8f508b447155a81b44e214475ab634a8Glenn Kasten            if (CC_UNLIKELY(!waitCount)) {
52334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                cblk->lock.unlock();
52489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                return WOULD_BLOCK;
52534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent            }
5261703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            if (!(cblk->flags & CBLK_INVALID_MSK)) {
5271703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                mLock.unlock();
5281703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs));
5291703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                cblk->lock.unlock();
5301703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                mLock.lock();
5311703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                if (mActive == 0) {
5321703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                    return status_t(STOPPED);
5331703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                }
5341703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                cblk->lock.lock();
5351703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            }
5361703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            if (cblk->flags & CBLK_INVALID_MSK) {
5371703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                goto create_new_record;
5381703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            }
539f6b1678f8f508b447155a81b44e214475ab634a8Glenn Kasten            if (CC_UNLIKELY(result != NO_ERROR)) {
5401dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent                cblk->waitTimeMs += waitTimeMs;
54189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) {
5425ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block                    ALOGW(   "obtainBuffer timed out (is the CPU pegged?) "
54389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                            "user=%08x, server=%08x", cblk->user, cblk->server);
54434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                    cblk->lock.unlock();
545a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                    // callback thread or sync event hasn't changed
5463acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten                    result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0);
5471703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                    cblk->lock.lock();
54834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                    if (result == DEAD_OBJECT) {
54938ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent                        android_atomic_or(CBLK_INVALID_ON, &cblk->flags);
5501703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurentcreate_new_record:
5511703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                        result = AudioRecord::restoreRecord_l(cblk);
5521703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                    }
5531703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                    if (result != NO_ERROR) {
5545ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block                        ALOGW("obtainBuffer create Track error %d", result);
5551703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                        cblk->lock.unlock();
5561703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                        return result;
55734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                    }
55889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                    cblk->waitTimeMs = 0;
55989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                }
56089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                if (--waitCount == 0) {
56134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                    cblk->lock.unlock();
56289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                    return TIMED_OUT;
56389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                }
56489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            }
56589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            // read the server count again
56689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        start_loop_here:
56789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            framesReady = cblk->framesReady();
56889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
56934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        cblk->lock.unlock();
57089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
57189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
57289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    cblk->waitTimeMs = 0;
5732986460984580833161bdaabc7f17da1005a8961Eric Laurent    // reset time out to running value after obtaining a buffer
5742986460984580833161bdaabc7f17da1005a8961Eric Laurent    cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
575c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent
57689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (framesReq > framesReady) {
57789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        framesReq = framesReady;
57889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
57989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
58089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t u = cblk->user;
58189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t bufferEnd = cblk->userBase + cblk->frameCount;
58289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
583a1472d9883e35edd280201c8be3191695007dfd4Marco Nelissen    if (framesReq > bufferEnd - u) {
58489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        framesReq = bufferEnd - u;
58589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
58689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
58789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->flags       = 0;
58889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->channelCount= mChannelCount;
58989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->format      = mFormat;
59089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->frameCount  = framesReq;
591c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    audioBuffer->size        = framesReq*cblk->frameSize;
59289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->raw         = (int8_t*)cblk->buffer(u);
59389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    active = mActive;
59489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return active ? status_t(NO_ERROR) : status_t(STOPPED);
59589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
59689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
59789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid AudioRecord::releaseBuffer(Buffer* audioBuffer)
59889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
5991703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    AutoMutex lock(mLock);
6001703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    mCblk->stepUser(audioBuffer->frameCount);
60189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
60289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
603606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenaudio_io_handle_t AudioRecord::getInput() const
6046100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent{
6051703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    AutoMutex lock(mLock);
606d1a243e41caffa8fd346907eed4625c9c47c1a86Eric Laurent    return mInput;
6071703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent}
6081703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
6091703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// must be called with mLock held
6101703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurentaudio_io_handle_t AudioRecord::getInput_l()
6111703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent{
61205bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent    mInput = AudioSystem::getInput(mInputSource,
6136100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent                                mCblk->sampleRate,
6147c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                mFormat,
6157c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                mChannelMask,
6167c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                (audio_in_acoustics_t)mFlags,
6177c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                mSessionId);
61805bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent    return mInput;
6196100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent}
6206100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent
621606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenint AudioRecord::getSessionId() const
622be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent{
623be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent    return mSessionId;
624be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent}
625be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent
62689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// -------------------------------------------------------------------------
62789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
62889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectssize_t AudioRecord::read(void* buffer, size_t userSize)
62989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
63089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    ssize_t read = 0;
63189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Buffer audioBuffer;
63289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    int8_t *dst = static_cast<int8_t*>(buffer);
63389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
63489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (ssize_t(userSize) < 0) {
63589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // sanity-check. user is most-likely passing an error code.
63629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("AudioRecord::read(buffer=%p, size=%u (%d)",
63789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                buffer, userSize, userSize);
63889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return BAD_VALUE;
63989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
64089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
6411703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    mLock.lock();
6421703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed
6431703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    // while we are accessing the cblk
644e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    sp<IAudioRecord> audioRecord = mAudioRecord;
645e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    sp<IMemory> iMem = mCblkMemory;
6461703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    mLock.unlock();
64789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
64889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    do {
64989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
650c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        audioBuffer.frameCount = userSize/frameSize();
65189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
65288335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent        // By using a wait count corresponding to twice the timeout period in
65388335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent        // obtainBuffer() we give a chance to recover once for a read timeout
65488335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent        // (if media_server crashed for instance) before returning a length of
65588335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent        // 0 bytes read to the client
65688335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent        status_t err = obtainBuffer(&audioBuffer, ((2 * MAX_RUN_TIMEOUT_MS) / WAIT_PERIOD_MS));
65789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (err < 0) {
65889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            // out of buffers, return #bytes written
65989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            if (err == status_t(NO_MORE_BUFFERS))
66089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                break;
66188335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent            if (err == status_t(TIMED_OUT))
66288335b1a749fe0157547907a2ce6c9632f4d2592Eric Laurent                err = 0;
66389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            return ssize_t(err);
66489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
66589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
66689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        size_t bytesRead = audioBuffer.size;
66789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        memcpy(dst, audioBuffer.i8, bytesRead);
66889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
66989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        dst += bytesRead;
67089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        userSize -= bytesRead;
67189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        read += bytesRead;
67289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
67389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        releaseBuffer(&audioBuffer);
67489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } while (userSize);
67589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
67689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return read;
67789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
67889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
67989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// -------------------------------------------------------------------------
68089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
68189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread)
68289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
68389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Buffer audioBuffer;
68489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t frames = mRemainingFrames;
68589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    size_t readSize;
68689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
6871703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    mLock.lock();
6881703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed
6891703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    // while we are accessing the cblk
690e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    sp<IAudioRecord> audioRecord = mAudioRecord;
691e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    sp<IMemory> iMem = mCblkMemory;
6921703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    audio_track_cblk_t* cblk = mCblk;
6931703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    mLock.unlock();
6941703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
69589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // Manage marker callback
6967d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi    if (!mMarkerReached && (mMarkerPosition > 0)) {
6971703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        if (cblk->user >= mMarkerPosition) {
69889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mCbf(EVENT_MARKER, mUserData, (void *)&mMarkerPosition);
6997d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi            mMarkerReached = true;
70089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
70189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
70289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
70389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // Manage new position callback
70489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mUpdatePeriod > 0) {
7051703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        while (cblk->user >= mNewPosition) {
70689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mCbf(EVENT_NEW_POS, mUserData, (void *)&mNewPosition);
70789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mNewPosition += mUpdatePeriod;
70889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
70989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
71089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
71189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    do {
71289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        audioBuffer.frameCount = frames;
713c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        // Calling obtainBuffer() with a wait count of 1
714c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        // limits wait time to WAIT_PERIOD_MS. This prevents from being
71589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // stuck here not being able to handle timed events (position, markers).
71689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        status_t err = obtainBuffer(&audioBuffer, 1);
71789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (err < NO_ERROR) {
71889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            if (err != TIMED_OUT) {
71929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                ALOGE_IF(err != status_t(NO_MORE_BUFFERS), "Error obtaining an audio buffer, giving up.");
72089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                return false;
72189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            }
72289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            break;
72389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
72489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (err == status_t(STOPPED)) return false;
72589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
72689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        size_t reqSize = audioBuffer.size;
72789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer);
72889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        readSize = audioBuffer.size;
72989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
73089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // Sanity check on returned size
731cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent        if (ssize_t(readSize) <= 0) {
732cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent            // The callback is done filling buffers
733cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent            // Keep this thread going to handle timed events and
734cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent            // still try to get more data in intervals of WAIT_PERIOD_MS
735cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent            // but don't just loop and block the CPU, so wait
736cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent            usleep(WAIT_PERIOD_MS*1000);
737cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent            break;
738cd6725a333395ffeac3215ea4bf834a95aaa8defEric Laurent        }
73989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (readSize > reqSize) readSize = reqSize;
74089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
74189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        audioBuffer.size = readSize;
742c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        audioBuffer.frameCount = readSize/frameSize();
74389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        frames -= audioBuffer.frameCount;
74489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
74589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        releaseBuffer(&audioBuffer);
74689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
74789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } while (frames);
74889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
749c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent
75089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // Manage overrun callback
7511703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    if (mActive && (cblk->framesAvailable() == 0)) {
7523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Overrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags);
75338ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        if (!(android_atomic_or(CBLK_UNDERRUN_ON, &cblk->flags) & CBLK_UNDERRUN_MSK)) {
75433797ea64d067dfeaacbfd7ebe7f3383b73961b5Eric Laurent            mCbf(EVENT_OVERRUN, mUserData, 0);
75589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
75689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
75789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
75889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (frames == 0) {
75989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mRemainingFrames = mNotificationFrames;
76089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } else {
76189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mRemainingFrames = frames;
76289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
76389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return true;
76489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
76589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
7661703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// must be called with mLock and cblk.lock held. Callers must also hold strong references on
7671703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// the IAudioRecord and IMemory in case they are recreated here.
7681703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// If the IAudioRecord is successfully restored, the cblk pointer is updated
7691703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurentstatus_t AudioRecord::restoreRecord_l(audio_track_cblk_t*& cblk)
7701703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent{
7711703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    status_t result;
7721703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
77338ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent    if (!(android_atomic_or(CBLK_RESTORING_ON, &cblk->flags) & CBLK_RESTORING_MSK)) {
7745ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("dead IAudioRecord, creating a new one");
7751703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        // signal old cblk condition so that other threads waiting for available buffers stop
7761703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        // waiting now
7771703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        cblk->cv.broadcast();
7781703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        cblk->lock.unlock();
7791703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
7801703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        // if the new IAudioRecord is created, openRecord_l() will modify the
7811703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        // following member variables: mAudioRecord, mCblkMemory and mCblk.
7821703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        // It will also delete the strong references on previous IAudioRecord and IMemory
7830d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi        result = openRecord_l(cblk->sampleRate, mFormat, mChannelMask,
784a075db4ff9b086ac2885df77bb6da0869293df92Glenn Kasten                mFrameCount, getInput_l());
7851703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        if (result == NO_ERROR) {
786a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent            // callback thread or sync event hasn't changed
7873acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten            result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0);
7881703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        }
7891703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        if (result != NO_ERROR) {
7901703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            mActive = false;
7911703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        }
7921703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
7931703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        // signal old cblk condition for other threads waiting for restore completion
79438ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        android_atomic_or(CBLK_RESTORED_ON, &cblk->flags);
7951703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        cblk->cv.broadcast();
7961703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    } else {
7971703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        if (!(cblk->flags & CBLK_RESTORED_MSK)) {
7985ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("dead IAudioRecord, waiting for a new one to be created");
7991703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            mLock.unlock();
8001703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            result = cblk->cv.waitRelative(cblk->lock, milliseconds(RESTORE_TIMEOUT_MS));
8011703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            cblk->lock.unlock();
8021703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            mLock.lock();
8031703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        } else {
8045ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("dead IAudioRecord, already restored");
8051703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            result = NO_ERROR;
8061703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            cblk->lock.unlock();
8071703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        }
8081703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        if (result != NO_ERROR || mActive == 0) {
8091703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            result = status_t(STOPPED);
8101703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        }
8111703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    }
8123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("restoreRecord_l() status %d mActive %d cblk %p, old cblk %p flags %08x old flags %08x",
813e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        result, mActive, mCblk, cblk, mCblk->flags, cblk->flags);
8141703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
8151703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    if (result == NO_ERROR) {
8161703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        // from now on we switch to the newly created cblk
8171703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        cblk = mCblk;
8181703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    }
8191703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    cblk->lock.lock();
8201703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
8215ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block    ALOGW_IF(result != NO_ERROR, "restoreRecord_l() error %d", result);
8221703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
8231703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    return result;
8241703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent}
8251703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
82689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// =========================================================================
82789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
82889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::ClientRecordThread::ClientRecordThread(AudioRecord& receiver, bool bCanCallJava)
82989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    : Thread(bCanCallJava), mReceiver(receiver)
83089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
83189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
83289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
83389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool AudioRecord::ClientRecordThread::threadLoop()
83489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
83589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mReceiver.processAudioBuffer(this);
83689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
83789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
8386dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kastenstatus_t AudioRecord::ClientRecordThread::readyToRun()
8396dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten{
8406dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten    AutoMutex(mReceiver.mLock);
8416dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten    while (mReceiver.mReadyToRun == WOULD_BLOCK) {
8426dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten        mReceiver.mCondition.wait(mReceiver.mLock);
8436dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten    }
8446dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten    return mReceiver.mReadyToRun;
8456dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten}
8466dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten
84789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// -------------------------------------------------------------------------
84889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
84989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}; // namespace android
850