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 <sys/resource.h>
22868a6a357018e5872e064b7a13a9b891e2078962Glenn Kasten#include <sys/types.h>
2389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
24868a6a357018e5872e064b7a13a9b891e2078962Glenn Kasten#include <binder/IPCThreadState.h>
25868a6a357018e5872e064b7a13a9b891e2078962Glenn Kasten#include <cutils/atomic.h>
26868a6a357018e5872e064b7a13a9b891e2078962Glenn Kasten#include <cutils/compiler.h>
2789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <media/AudioRecord.h>
28868a6a357018e5872e064b7a13a9b891e2078962Glenn Kasten#include <media/AudioSystem.h>
29868a6a357018e5872e064b7a13a9b891e2078962Glenn Kasten#include <system/audio.h>
3089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <utils/Log.h>
3189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
32868a6a357018e5872e064b7a13a9b891e2078962Glenn Kasten#include <private/media/AudioTrackShared.h>
3389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
3489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectnamespace android {
3515304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh// ---------------------------------------------------------------------------
3615304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh
3715304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh// static
3815304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yehstatus_t AudioRecord::getMinFrameCount(
3915304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh        int* frameCount,
4015304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh        uint32_t sampleRate,
4158f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten        audio_format_t format,
42dd8104cc5367262f0e5f13df4e79f131e8d560bbGlenn Kasten        audio_channel_mask_t channelMask)
4315304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh{
4404cd0186305e2b59d23c9147787046c6662029ccGlenn Kasten    if (frameCount == NULL) return BAD_VALUE;
4504cd0186305e2b59d23c9147787046c6662029ccGlenn Kasten
4604cd0186305e2b59d23c9147787046c6662029ccGlenn Kasten    // default to 0 in case of error
4704cd0186305e2b59d23c9147787046c6662029ccGlenn Kasten    *frameCount = 0;
4804cd0186305e2b59d23c9147787046c6662029ccGlenn Kasten
4915304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    size_t size = 0;
50dd8104cc5367262f0e5f13df4e79f131e8d560bbGlenn Kasten    if (AudioSystem::getInputBufferSize(sampleRate, format, channelMask, &size)
5115304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh            != NO_ERROR) {
5229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("AudioSystem could not query the input buffer size.");
5315304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh        return NO_INIT;
5415304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    }
5515304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh
5615304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    if (size == 0) {
57dd8104cc5367262f0e5f13df4e79f131e8d560bbGlenn Kasten        ALOGE("Unsupported configuration: sampleRate %d, format %d, channelMask %#x",
58dd8104cc5367262f0e5f13df4e79f131e8d560bbGlenn Kasten            sampleRate, format, channelMask);
5915304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh        return BAD_VALUE;
6015304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    }
6115304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh
6215304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    // We double the size of input buffer for ping pong use of record buffer.
6315304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    size <<= 1;
6415304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh
65fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (audio_is_linear_pcm(format)) {
66dd8104cc5367262f0e5f13df4e79f131e8d560bbGlenn Kasten        int channelCount = popcount(channelMask);
67671a636931295d9c33ffca74551a804479d01241Eric Laurent        size /= channelCount * audio_bytes_per_sample(format);
6815304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    }
6915304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh
7015304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    *frameCount = size;
7115304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    return NO_ERROR;
7215304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh}
7389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
7489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// ---------------------------------------------------------------------------
7589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
7689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::AudioRecord()
77879135196fd1c97deefc538c888037c56c2879a7Glenn Kasten    : mStatus(NO_INIT), mSessionId(0),
78a636433cbd09c0708b85f337ef45c0cdef3bcb4dGlenn Kasten      mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT)
7989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
8089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
8189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
8289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::AudioRecord(
83eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kasten        audio_source_t inputSource,
8489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        uint32_t sampleRate,
8558f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten        audio_format_t format,
86624a7fcb377f2a40109c16de5109ae8ea1f67a69Glenn Kasten        audio_channel_mask_t channelMask,
8789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int frameCount,
8889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        callback_t cbf,
8989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        void* user,
90be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        int notificationFrames,
91be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        int sessionId)
92879135196fd1c97deefc538c888037c56c2879a7Glenn Kasten    : mStatus(NO_INIT), mSessionId(0),
93a636433cbd09c0708b85f337ef45c0cdef3bcb4dGlenn Kasten      mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT)
9489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
950d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi    mStatus = set(inputSource, sampleRate, format, channelMask,
96f92eec53f886f43e4374a36195be55f2a7bbcf36Glenn Kasten            frameCount, cbf, user, notificationFrames, sessionId);
9789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
9889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
9989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAudioRecord::~AudioRecord()
10089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
10189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mStatus == NO_ERROR) {
10289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // Make sure that callback function exits in the case where
10389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // it is looping on buffer empty condition in obtainBuffer().
10489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // Otherwise the callback thread will never exit.
10589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        stop();
10668337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten        if (mAudioRecordThread != 0) {
10768337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten            mAudioRecordThread->requestExit();  // see comment in AudioRecord.h
10868337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten            mAudioRecordThread->requestExitAndWait();
10968337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten            mAudioRecordThread.clear();
11089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
11189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mAudioRecord.clear();
11289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        IPCThreadState::self()->flushCommands();
1133a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen        AudioSystem::releaseAudioSessionId(mSessionId);
11489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
11589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
11689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
11789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::set(
118eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kasten        audio_source_t inputSource,
11989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        uint32_t sampleRate,
12058f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten        audio_format_t format,
121624a7fcb377f2a40109c16de5109ae8ea1f67a69Glenn Kasten        audio_channel_mask_t channelMask,
12289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int frameCount,
12389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        callback_t cbf,
12489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        void* user,
12589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int notificationFrames,
126be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        bool threadCanCallJava,
127be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        int sessionId)
12889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
12989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
130624a7fcb377f2a40109c16de5109ae8ea1f67a69Glenn Kasten    ALOGV("set(): sampleRate %d, channelMask %#x, frameCount %d",sampleRate, channelMask, frameCount);
1311703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
1321703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    AutoMutex lock(mLock);
1331703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
1341dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent    if (mAudioRecord != 0) {
13589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return INVALID_OPERATION;
13689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
13789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
138c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    if (inputSource == AUDIO_SOURCE_DEFAULT) {
139c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        inputSource = AUDIO_SOURCE_MIC;
14089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
14189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
14289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (sampleRate == 0) {
14389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        sampleRate = DEFAULT_SAMPLE_RATE;
14489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
14589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // these below should probably come from the audioFlinger too...
14658f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten    if (format == AUDIO_FORMAT_DEFAULT) {
147fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        format = AUDIO_FORMAT_PCM_16_BIT;
14889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
149c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    // validate parameters
150fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (!audio_is_valid_format(format)) {
15129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Invalid format");
152c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        return BAD_VALUE;
15389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
15489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
1550d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi    if (!audio_is_input_channel(channelMask)) {
15689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return BAD_VALUE;
15789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
158be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent
1590d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi    int channelCount = popcount(channelMask);
160c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent
1617c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (sessionId == 0 ) {
1627c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        mSessionId = AudioSystem::newAudioSessionId();
1637c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    } else {
1647c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        mSessionId = sessionId;
1657c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
1663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("set(): mSessionId %d", mSessionId);
1677c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
1686100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent    audio_io_handle_t input = AudioSystem::getInput(inputSource,
1697c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                                    sampleRate,
1707c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                                    format,
1717c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                                    channelMask,
1727c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                                    mSessionId);
1736100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent    if (input == 0) {
17429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Could not get audio input for record source %d", inputSource);
17589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return BAD_VALUE;
17689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
17789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
17889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // validate framecount
17915304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    int minFrameCount = 0;
1806f744d75d3439f7984245e3c489cc7cf91cea41cEric Laurent    status_t status = getMinFrameCount(&minFrameCount, sampleRate, format, channelMask);
18115304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh    if (status != NO_ERROR) {
18215304d601cbf83be6519ca53e1a26b97d50d0192Chia-chi Yeh        return status;
183c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    }
1843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioRecord::set() minFrameCount = %d", minFrameCount);
18589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
18689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (frameCount == 0) {
18789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        frameCount = minFrameCount;
18889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } else if (frameCount < minFrameCount) {
18989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return BAD_VALUE;
19089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
19189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
19289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (notificationFrames == 0) {
19389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        notificationFrames = frameCount/2;
19489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
19589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
19634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    // create the IAudioRecord
1970d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi    status = openRecord_l(sampleRate, format, channelMask,
198a075db4ff9b086ac2885df77bb6da0869293df92Glenn Kasten                        frameCount, input);
19934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    if (status != NO_ERROR) {
20089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return status;
20189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
20234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent
203a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten    if (cbf != NULL) {
20468337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten        mAudioRecordThread = new AudioRecordThread(*this, threadCanCallJava);
20568337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten        mAudioRecordThread->run("AudioRecord", ANDROID_PRIORITY_AUDIO);
20689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
20789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
20889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mStatus = NO_ERROR;
20989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
21089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mFormat = format;
21189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // Update buffer size in case it has been limited by AudioFlinger during track creation
21289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mFrameCount = mCblk->frameCount;
213c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    mChannelCount = (uint8_t)channelCount;
2140d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi    mChannelMask = channelMask;
21568337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten    mActive = false;
21689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mCbf = cbf;
21789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mNotificationFrames = notificationFrames;
21889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mRemainingFrames = notificationFrames;
21989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mUserData = user;
22089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // TODO: add audio hardware input latency here
221573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent    mLatency = (1000*mFrameCount) / sampleRate;
22289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mMarkerPosition = 0;
2237d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi    mMarkerReached = false;
22489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mNewPosition = 0;
22589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mUpdatePeriod = 0;
226eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kasten    mInputSource = inputSource;
22705bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent    mInput = input;
2283a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen    AudioSystem::acquireAudioSessionId(mSessionId);
22989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
23089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
23189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
23289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
23389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::initCheck() const
23489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
23589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mStatus;
23689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
23789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
23889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// -------------------------------------------------------------------------
23989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
24089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectuint32_t AudioRecord::latency() const
24189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
24289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mLatency;
24389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
24489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
24558f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kastenaudio_format_t AudioRecord::format() const
24689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
24789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mFormat;
24889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
24989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
25089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint AudioRecord::channelCount() const
25189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
25289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mChannelCount;
25389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
25489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
25589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectuint32_t AudioRecord::frameCount() const
25689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
25789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mFrameCount;
25889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
25989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
260b9980659501d0428d65d8292f3c32da69d37fbd2Glenn Kastensize_t AudioRecord::frameSize() const
26189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
262fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (audio_is_linear_pcm(mFormat)) {
263671a636931295d9c33ffca74551a804479d01241Eric Laurent        return channelCount()*audio_bytes_per_sample(mFormat);
264c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    } else {
265c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        return sizeof(uint8_t);
266c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    }
26789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
26889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
269eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kastenaudio_source_t AudioRecord::inputSource() const
270f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent{
271eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kasten    return mInputSource;
272f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent}
273f5879c1448cc6aebc51b26d3ec2399d66144f8f4Eric Laurent
27489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// -------------------------------------------------------------------------
27589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
276a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurentstatus_t AudioRecord::start(AudioSystem::sync_event_t event, int triggerSession)
27789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
27889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    status_t ret = NO_ERROR;
27968337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten    sp<AudioRecordThread> t = mAudioRecordThread;
28089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
281a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent    ALOGV("start, sync event %d trigger session %d", event, triggerSession);
28289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
283f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent    AutoMutex lock(mLock);
2841703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed
2851703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    // while we are accessing the cblk
286e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    sp<IAudioRecord> audioRecord = mAudioRecord;
287e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten    sp<IMemory> iMem = mCblkMemory;
2881703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    audio_track_cblk_t* cblk = mCblk;
2891703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
29068337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten    if (!mActive) {
29168337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten        mActive = true;
2926dbc1359f778575d09d6da722b060a6d72c2e7c5Glenn Kasten
2931703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        cblk->lock.lock();
2941703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        if (!(cblk->flags & CBLK_INVALID_MSK)) {
2951703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            cblk->lock.unlock();
2963acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten            ALOGV("mAudioRecord->start()");
2973acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten            ret = mAudioRecord->start(event, triggerSession);
2981703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            cblk->lock.lock();
2991703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            if (ret == DEAD_OBJECT) {
30038ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent                android_atomic_or(CBLK_INVALID_ON, &cblk->flags);
3016100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent            }
3026100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent        }
3031703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        if (cblk->flags & CBLK_INVALID_MSK) {
3041703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            ret = restoreRecord_l(cblk);
3051703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        }
3061703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        cblk->lock.unlock();
3076100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent        if (ret == NO_ERROR) {
3081703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            mNewPosition = cblk->user + mUpdatePeriod;
3092986460984580833161bdaabc7f17da1005a8961Eric Laurent            cblk->bufferTimeoutMs = (event == AudioSystem::SYNC_EVENT_NONE) ? MAX_RUN_TIMEOUT_MS :
3102986460984580833161bdaabc7f17da1005a8961Eric Laurent                                            AudioSystem::kSyncRecordStartTimeOutMs;
3111703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            cblk->waitTimeMs = 0;
3126100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent            if (t != 0) {
31368337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten                t->resume();
314c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent            } else {
315879135196fd1c97deefc538c888037c56c2879a7Glenn Kasten                mPreviousPriority = getpriority(PRIO_PROCESS, 0);
316a636433cbd09c0708b85f337ef45c0cdef3bcb4dGlenn Kasten                get_sched_policy(0, &mPreviousSchedulingGroup);
317879135196fd1c97deefc538c888037c56c2879a7Glenn Kasten                androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO);
318c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent            }
3196100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent        } else {
32068337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten            mActive = false;
32189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
32289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
32389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
32489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return ret;
32589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
32689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
327d64cd233eef39430561c1e1df423336a199cc5d7Glenn Kastenvoid AudioRecord::stop()
32889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
32968337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten    sp<AudioRecordThread> t = mAudioRecordThread;
33089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
3313856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("stop");
33289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
333f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent    AutoMutex lock(mLock);
33468337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten    if (mActive) {
33568337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten        mActive = false;
3361dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent        mCblk->cv.signal();
33789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mAudioRecord->stop();
3387d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi        // the record head position will reset to 0, so if a marker is set, we need
3397d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi        // to activate it again
3407d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi        mMarkerReached = false;
34189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (t != 0) {
34268337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten            t->pause();
34389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        } else {
344879135196fd1c97deefc538c888037c56c2879a7Glenn Kasten            setpriority(PRIO_PROCESS, 0, mPreviousPriority);
345a636433cbd09c0708b85f337ef45c0cdef3bcb4dGlenn Kasten            set_sched_policy(0, mPreviousSchedulingGroup);
34689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
34789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
34889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
34989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
35089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool AudioRecord::stopped() const
35189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
35268337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten    AutoMutex lock(mLock);
35389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return !mActive;
35489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
35589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
356606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenuint32_t AudioRecord::getSampleRate() const
357573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent{
358573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent    return mCblk->sampleRate;
359573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent}
360573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent
36189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::setMarkerPosition(uint32_t marker)
36289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
363a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten    if (mCbf == NULL) return INVALID_OPERATION;
36489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
365955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten    AutoMutex lock(mLock);
36689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mMarkerPosition = marker;
3677d563247cdac0509009d579bbf849157d47c38a9Jean-Michel Trivi    mMarkerReached = false;
36889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
36989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
37089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
37189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
372606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenstatus_t AudioRecord::getMarkerPosition(uint32_t *marker) const
37389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
374a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten    if (marker == NULL) return BAD_VALUE;
37589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
376955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten    AutoMutex lock(mLock);
37789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *marker = mMarkerPosition;
37889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
37989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
38089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
38189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
38289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod)
38389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
384a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten    if (mCbf == NULL) return INVALID_OPERATION;
38589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
38689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t curPosition;
38789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    getPosition(&curPosition);
388955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten
389955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten    AutoMutex lock(mLock);
39089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mNewPosition = curPosition + updatePeriod;
39189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mUpdatePeriod = updatePeriod;
39289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
39389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
39489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
39589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
396606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenstatus_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod) const
39789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
398a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten    if (updatePeriod == NULL) return BAD_VALUE;
39989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
400955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten    AutoMutex lock(mLock);
40189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *updatePeriod = mUpdatePeriod;
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::getPosition(uint32_t *position) const
40789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
408a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten    if (position == NULL) return BAD_VALUE;
40989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
4101703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    AutoMutex lock(mLock);
41189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *position = mCblk->user;
41289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
41389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
41489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
41589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
416606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenunsigned int AudioRecord::getInputFramesLost() const
41705bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent{
418bf04a5d7f287fc712e0ed91849dc85c90c1e182dGlenn Kasten    // no need to check mActive, because if inactive this will return 0, which is what we want
419bf04a5d7f287fc712e0ed91849dc85c90c1e182dGlenn Kasten    return AudioSystem::getInputFramesLost(mInput);
42005bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent}
42189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
42289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// -------------------------------------------------------------------------
42389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
4241703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// must be called with mLock held
4251703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurentstatus_t AudioRecord::openRecord_l(
42634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        uint32_t sampleRate,
42758f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten        audio_format_t format,
428624a7fcb377f2a40109c16de5109ae8ea1f67a69Glenn Kasten        audio_channel_mask_t channelMask,
42934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        int frameCount,
4306100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent        audio_io_handle_t input)
43134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent{
43234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    status_t status;
43334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
43434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    if (audioFlinger == 0) {
43534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        return NO_INIT;
43634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    }
43734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent
4381879fff068422852c1483dcf8365c2ff0e2fadfcGlenn Kasten    pid_t tid = -1;
4391879fff068422852c1483dcf8365c2ff0e2fadfcGlenn Kasten    // FIXME see similar logic at AudioTrack
4401879fff068422852c1483dcf8365c2ff0e2fadfcGlenn Kasten
441955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten    int originalSessionId = mSessionId;
4426100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent    sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), input,
44334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                                                       sampleRate, format,
4440d255b2d9061ba31f13ada3fc0f7e51916407176Jean-Michel Trivi                                                       channelMask,
44534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                                                       frameCount,
446a075db4ff9b086ac2885df77bb6da0869293df92Glenn Kasten                                                       IAudioFlinger::TRACK_DEFAULT,
4471879fff068422852c1483dcf8365c2ff0e2fadfcGlenn Kasten                                                       tid,
448be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent                                                       &mSessionId,
44934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                                                       &status);
450955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten    ALOGE_IF(originalSessionId != 0 && mSessionId != originalSessionId,
451955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten            "session ID changed from %d to %d", originalSessionId, mSessionId);
4523a34befc6fb04a4945a849e8bda8b84e4bf973feMarco Nelissen
45334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    if (record == 0) {
45429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("AudioFlinger could not create record track, status: %d", status);
45534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        return status;
45634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    }
45734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    sp<IMemory> cblk = record->getCblk();
45834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    if (cblk == 0) {
45929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Could not get control block");
46034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        return NO_INIT;
46134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    }
46234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    mAudioRecord.clear();
46334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    mAudioRecord = record;
46434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    mCblkMemory.clear();
46534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    mCblkMemory = cblk;
46634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
46734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
46838ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent    android_atomic_and(~CBLK_DIRECTION_MSK, &mCblk->flags);
4696100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent    mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
4706100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent    mCblk->waitTimeMs = 0;
47134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent    return NO_ERROR;
47234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent}
47334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent
47489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
47589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
4761703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    AutoMutex lock(mLock);
47768337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten    bool active;
478d0965dde97f2815ae0a15fe6b40946f8a741a81eGlenn Kasten    status_t result = NO_ERROR;
47989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audio_track_cblk_t* cblk = mCblk;
48089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t framesReq = audioBuffer->frameCount;
4811dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent    uint32_t waitTimeMs = (waitCount < 0) ? cblk->bufferTimeoutMs : WAIT_PERIOD_MS;
48289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
48389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->frameCount  = 0;
48489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->size        = 0;
48589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
48689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t framesReady = cblk->framesReady();
48789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
48889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (framesReady == 0) {
48934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        cblk->lock.lock();
49089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        goto start_loop_here;
49189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        while (framesReady == 0) {
49289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            active = mActive;
493f6b1678f8f508b447155a81b44e214475ab634a8Glenn Kasten            if (CC_UNLIKELY(!active)) {
49434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                cblk->lock.unlock();
49589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                return NO_MORE_BUFFERS;
49634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent            }
497f6b1678f8f508b447155a81b44e214475ab634a8Glenn Kasten            if (CC_UNLIKELY(!waitCount)) {
49834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                cblk->lock.unlock();
49989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                return WOULD_BLOCK;
50034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent            }
5011703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            if (!(cblk->flags & CBLK_INVALID_MSK)) {
5021703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                mLock.unlock();
5031703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs));
5041703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                cblk->lock.unlock();
5051703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                mLock.lock();
50668337edf595a0c345ba4b8adcd4f1e541a1d7eb7Glenn Kasten                if (!mActive) {
5071703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                    return status_t(STOPPED);
5081703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                }
5091703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                cblk->lock.lock();
5101703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            }
5111703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            if (cblk->flags & CBLK_INVALID_MSK) {
5121703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                goto create_new_record;
5131703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            }
514f6b1678f8f508b447155a81b44e214475ab634a8Glenn Kasten            if (CC_UNLIKELY(result != NO_ERROR)) {
5151dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent                cblk->waitTimeMs += waitTimeMs;
51689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) {
5175ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block                    ALOGW(   "obtainBuffer timed out (is the CPU pegged?) "
51889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                            "user=%08x, server=%08x", cblk->user, cblk->server);
51934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                    cblk->lock.unlock();
520a011e35b22f95f558d81dc9c94b68b1465c4661dEric Laurent                    // callback thread or sync event hasn't changed
5213acbd053c842e76e1a40fc8a0bf62de87eebf00fGlenn Kasten                    result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0);
5221703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                    cblk->lock.lock();
52334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                    if (result == DEAD_OBJECT) {
52438ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent                        android_atomic_or(CBLK_INVALID_ON, &cblk->flags);
5251703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurentcreate_new_record:
5261703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                        result = AudioRecord::restoreRecord_l(cblk);
5271703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                    }
5281703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                    if (result != NO_ERROR) {
5295ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block                        ALOGW("obtainBuffer create Track error %d", result);
5301703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                        cblk->lock.unlock();
5311703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                        return result;
53234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                    }
53389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                    cblk->waitTimeMs = 0;
53489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                }
53589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                if (--waitCount == 0) {
53634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                    cblk->lock.unlock();
53789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                    return TIMED_OUT;
53889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                }
53989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            }
54089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            // read the server count again
54189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        start_loop_here:
54289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            framesReady = cblk->framesReady();
54389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
54434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        cblk->lock.unlock();
54589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
54689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
54789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    cblk->waitTimeMs = 0;
5482986460984580833161bdaabc7f17da1005a8961Eric Laurent    // reset time out to running value after obtaining a buffer
5492986460984580833161bdaabc7f17da1005a8961Eric Laurent    cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
550c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent
55189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (framesReq > framesReady) {
55289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        framesReq = framesReady;
55389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
55489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
55589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t u = cblk->user;
55689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t bufferEnd = cblk->userBase + cblk->frameCount;
55789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
558a1472d9883e35edd280201c8be3191695007dfd4Marco Nelissen    if (framesReq > bufferEnd - u) {
55989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        framesReq = bufferEnd - u;
56089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
56189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
56289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->flags       = 0;
56389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->channelCount= mChannelCount;
56489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->format      = mFormat;
56589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->frameCount  = framesReq;
566c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    audioBuffer->size        = framesReq*cblk->frameSize;
56789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    audioBuffer->raw         = (int8_t*)cblk->buffer(u);
56889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    active = mActive;
56989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return active ? status_t(NO_ERROR) : status_t(STOPPED);
57089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
57189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
57289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid AudioRecord::releaseBuffer(Buffer* audioBuffer)
57389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
5741703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    AutoMutex lock(mLock);
5751703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    mCblk->stepUser(audioBuffer->frameCount);
57689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
57789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
578606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenaudio_io_handle_t AudioRecord::getInput() const
5796100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent{
5801703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    AutoMutex lock(mLock);
581d1a243e41caffa8fd346907eed4625c9c47c1a86Eric Laurent    return mInput;
5821703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent}
5831703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
5841703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent// must be called with mLock held
5851703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurentaudio_io_handle_t AudioRecord::getInput_l()
5861703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent{
58705bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent    mInput = AudioSystem::getInput(mInputSource,
5886100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent                                mCblk->sampleRate,
5897c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                mFormat,
5907c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                mChannelMask,
5917c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                mSessionId);
59205bca2fde53bfe3063d2a0a877f2b6bfdd6052cfEric Laurent    return mInput;
5936100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent}
5946100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent
595606ee61616efdba4696ae591ad10a4be33d8c946Glenn Kastenint AudioRecord::getSessionId() const
596be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent{
597955e78180ac6111c54f50930b0c4c12395e86cf7Glenn Kasten    // no lock needed because session ID doesn't change after first set()
598be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent    return mSessionId;
599be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent}
600be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent
60189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// -------------------------------------------------------------------------
60289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
60389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectssize_t AudioRecord::read(void* buffer, size_t userSize)
60489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
60589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    ssize_t read = 0;
60689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Buffer audioBuffer;
60789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    int8_t *dst = static_cast<int8_t*>(buffer);