am fcae6c71: am 67b69292: Merge change I93f500a5 into eclair

Merge commit 'fcae6c71794696a074cabf20beeb02fd87853e30' into eclair-mr2-plus-aosp

* commit 'fcae6c71794696a074cabf20beeb02fd87853e30':
  Fix issue 2203561: Sholes: audio playing out of earpiece.
This commit is contained in:
Eric Laurent
2009-11-05 01:55:51 -08:00
committed by Android Git Automerger
9 changed files with 244 additions and 114 deletions

View File

@ -79,7 +79,7 @@ static void android_media_ToneGenerator_release(JNIEnv *env, jobject thiz) {
static void android_media_ToneGenerator_native_setup(JNIEnv *env, jobject thiz, static void android_media_ToneGenerator_native_setup(JNIEnv *env, jobject thiz,
jint streamType, jint volume) { jint streamType, jint volume) {
ToneGenerator *lpToneGen = new ToneGenerator(streamType, AudioSystem::linearToLog(volume)); ToneGenerator *lpToneGen = new ToneGenerator(streamType, AudioSystem::linearToLog(volume), true);
env->SetIntField(thiz, fields.context, 0); env->SetIntField(thiz, fields.context, 0);

View File

@ -314,6 +314,11 @@ private:
}; };
bool processAudioBuffer(const sp<ClientRecordThread>& thread); bool processAudioBuffer(const sp<ClientRecordThread>& thread);
status_t openRecord(uint32_t sampleRate,
int format,
int channelCount,
int frameCount,
uint32_t flags);
sp<IAudioRecord> mAudioRecord; sp<IAudioRecord> mAudioRecord;
sp<IMemory> mCblkMemory; sp<IMemory> mCblkMemory;
@ -341,6 +346,7 @@ private:
uint32_t mNewPosition; uint32_t mNewPosition;
uint32_t mUpdatePeriod; uint32_t mUpdatePeriod;
audio_io_handle_t mInput; audio_io_handle_t mInput;
uint32_t mFlags;
}; };
}; // namespace android }; // namespace android

View File

@ -391,6 +391,14 @@ private:
}; };
bool processAudioBuffer(const sp<AudioTrackThread>& thread); bool processAudioBuffer(const sp<AudioTrackThread>& thread);
status_t createTrack(int streamType,
uint32_t sampleRate,
int format,
int channelCount,
int frameCount,
uint32_t flags,
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output);
sp<IAudioTrack> mAudioTrack; sp<IAudioTrack> mAudioTrack;
sp<IMemory> mCblkMemory; sp<IMemory> mCblkMemory;

View File

@ -151,7 +151,7 @@ public:
NUM_SUP_TONES = LAST_SUP_TONE-FIRST_SUP_TONE+1 NUM_SUP_TONES = LAST_SUP_TONE-FIRST_SUP_TONE+1
}; };
ToneGenerator(int streamType, float volume); ToneGenerator(int streamType, float volume, bool threadCanCallJava = false);
~ToneGenerator(); ~ToneGenerator();
bool startTone(int toneType, int durationMs = -1); bool startTone(int toneType, int durationMs = -1);
@ -242,6 +242,7 @@ private:
static const ToneDescriptor sToneDescriptors[]; static const ToneDescriptor sToneDescriptors[];
bool mThreadCanCallJava;
unsigned int mTotalSmp; // Total number of audio samples played (gives current time) unsigned int mTotalSmp; // Total number of audio samples played (gives current time)
unsigned int mNextSegSmp; // Position of next segment transition expressed in samples unsigned int mNextSegSmp; // Position of next segment transition expressed in samples
// NOTE: because mTotalSmp, mNextSegSmp are stored on 32 bit, current design will operate properly // NOTE: because mTotalSmp, mNextSegSmp are stored on 32 bit, current design will operate properly

View File

@ -101,11 +101,6 @@ status_t AudioRecord::set(
return INVALID_OPERATION; return INVALID_OPERATION;
} }
const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
if (audioFlinger == 0) {
return NO_INIT;
}
if (inputSource == AUDIO_SOURCE_DEFAULT) { if (inputSource == AUDIO_SOURCE_DEFAULT) {
inputSource = AUDIO_SOURCE_MIC; inputSource = AUDIO_SOURCE_MIC;
} }
@ -171,22 +166,14 @@ status_t AudioRecord::set(
notificationFrames = frameCount/2; notificationFrames = frameCount/2;
} }
// open record channel // create the IAudioRecord
status_t status; status_t status = openRecord(sampleRate, format, channelCount,
sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), mInput, frameCount, flags);
sampleRate, format,
channelCount, if (status != NO_ERROR) {
frameCount,
((uint16_t)flags) << 16,
&status);
if (record == 0) {
LOGE("AudioFlinger could not create record track, status: %d", status);
return status; return status;
} }
sp<IMemory> cblk = record->getCblk();
if (cblk == 0) {
return NO_INIT;
}
if (cbf != 0) { if (cbf != 0) {
mClientRecordThread = new ClientRecordThread(*this, threadCanCallJava); mClientRecordThread = new ClientRecordThread(*this, threadCanCallJava);
if (mClientRecordThread == 0) { if (mClientRecordThread == 0) {
@ -196,11 +183,6 @@ status_t AudioRecord::set(
mStatus = NO_ERROR; mStatus = NO_ERROR;
mAudioRecord = record;
mCblkMemory = cblk;
mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
mCblk->out = 0;
mFormat = format; mFormat = format;
// Update buffer size in case it has been limited by AudioFlinger during track creation // Update buffer size in case it has been limited by AudioFlinger during track creation
mFrameCount = mCblk->frameCount; mFrameCount = mCblk->frameCount;
@ -217,6 +199,7 @@ status_t AudioRecord::set(
mNewPosition = 0; mNewPosition = 0;
mUpdatePeriod = 0; mUpdatePeriod = 0;
mInputSource = (uint8_t)inputSource; mInputSource = (uint8_t)inputSource;
mFlags = flags;
return NO_ERROR; return NO_ERROR;
} }
@ -284,15 +267,26 @@ status_t AudioRecord::start()
if (android_atomic_or(1, &mActive) == 0) { if (android_atomic_or(1, &mActive) == 0) {
ret = AudioSystem::startInput(mInput); ret = AudioSystem::startInput(mInput);
if (ret == NO_ERROR) { if (ret == NO_ERROR) {
mNewPosition = mCblk->user + mUpdatePeriod;
mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
mCblk->waitTimeMs = 0;
if (t != 0) {
t->run("ClientRecordThread", THREAD_PRIORITY_AUDIO_CLIENT);
} else {
setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT);
}
ret = mAudioRecord->start(); ret = mAudioRecord->start();
if (ret == DEAD_OBJECT) {
LOGV("start() dead IAudioRecord: creating a new one");
ret = openRecord(mCblk->sampleRate, mFormat, mChannelCount,
mFrameCount, mFlags);
}
if (ret == NO_ERROR) {
mNewPosition = mCblk->user + mUpdatePeriod;
mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
mCblk->waitTimeMs = 0;
if (t != 0) {
t->run("ClientRecordThread", THREAD_PRIORITY_AUDIO_CLIENT);
} else {
setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT);
}
} else {
LOGV("start() failed");
AudioSystem::stopInput(mInput);
android_atomic_and(~1, &mActive);
}
} }
} }
@ -396,10 +390,48 @@ status_t AudioRecord::getPosition(uint32_t *position)
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
status_t AudioRecord::openRecord(
uint32_t sampleRate,
int format,
int channelCount,
int frameCount,
uint32_t flags)
{
status_t status;
const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
if (audioFlinger == 0) {
return NO_INIT;
}
sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), mInput,
sampleRate, format,
channelCount,
frameCount,
((uint16_t)flags) << 16,
&status);
if (record == 0) {
LOGE("AudioFlinger could not create record track, status: %d", status);
return status;
}
sp<IMemory> cblk = record->getCblk();
if (cblk == 0) {
LOGE("Could not get control block");
return NO_INIT;
}
mAudioRecord.clear();
mAudioRecord = record;
mCblkMemory.clear();
mCblkMemory = cblk;
mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
mCblk->out = 0;
return NO_ERROR;
}
status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
{ {
int active; int active;
int timeout = 0;
status_t result; status_t result;
audio_track_cblk_t* cblk = mCblk; audio_track_cblk_t* cblk = mCblk;
uint32_t framesReq = audioBuffer->frameCount; uint32_t framesReq = audioBuffer->frameCount;
@ -411,25 +443,40 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
uint32_t framesReady = cblk->framesReady(); uint32_t framesReady = cblk->framesReady();
if (framesReady == 0) { if (framesReady == 0) {
Mutex::Autolock _l(cblk->lock); cblk->lock.lock();
goto start_loop_here; goto start_loop_here;
while (framesReady == 0) { while (framesReady == 0) {
active = mActive; active = mActive;
if (UNLIKELY(!active)) if (UNLIKELY(!active)) {
cblk->lock.unlock();
return NO_MORE_BUFFERS; return NO_MORE_BUFFERS;
if (UNLIKELY(!waitCount)) }
if (UNLIKELY(!waitCount)) {
cblk->lock.unlock();
return WOULD_BLOCK; return WOULD_BLOCK;
timeout = 0; }
result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs)); result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs));
if (__builtin_expect(result!=NO_ERROR, false)) { if (__builtin_expect(result!=NO_ERROR, false)) {
cblk->waitTimeMs += waitTimeMs; cblk->waitTimeMs += waitTimeMs;
if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) { if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) {
LOGW( "obtainBuffer timed out (is the CPU pegged?) " LOGW( "obtainBuffer timed out (is the CPU pegged?) "
"user=%08x, server=%08x", cblk->user, cblk->server); "user=%08x, server=%08x", cblk->user, cblk->server);
timeout = 1; cblk->lock.unlock();
result = mAudioRecord->start();
if (result == DEAD_OBJECT) {
LOGW("obtainBuffer() dead IAudioRecord: creating a new one");
result = openRecord(cblk->sampleRate, mFormat, mChannelCount,
mFrameCount, mFlags);
if (result == NO_ERROR) {
cblk = mCblk;
cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
}
}
cblk->lock.lock();
cblk->waitTimeMs = 0; cblk->waitTimeMs = 0;
} }
if (--waitCount == 0) { if (--waitCount == 0) {
cblk->lock.unlock();
return TIMED_OUT; return TIMED_OUT;
} }
} }
@ -437,13 +484,9 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
start_loop_here: start_loop_here:
framesReady = cblk->framesReady(); framesReady = cblk->framesReady();
} }
cblk->lock.unlock();
} }
LOGW_IF(timeout,
"*** SERIOUS WARNING *** obtainBuffer() timed out "
"but didn't need to be locked. We recovered, but "
"this shouldn't happen (user=%08x, server=%08x)", cblk->user, cblk->server);
cblk->waitTimeMs = 0; cblk->waitTimeMs = 0;
if (framesReq > framesReady) { if (framesReq > framesReady) {

View File

@ -122,11 +122,6 @@ status_t AudioTrack::set(
return INVALID_OPERATION; return INVALID_OPERATION;
} }
const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
if (audioFlinger == 0) {
LOGE("Could not get audioflinger");
return NO_INIT;
}
int afSampleRate; int afSampleRate;
if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) { if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) {
return NO_INIT; return NO_INIT;
@ -217,28 +212,16 @@ status_t AudioTrack::set(
} }
} }
// create the track mVolume[LEFT] = 1.0f;
status_t status; mVolume[RIGHT] = 1.0f;
sp<IAudioTrack> track = audioFlinger->createTrack(getpid(), // create the IAudioTrack
streamType, status_t status = createTrack(streamType, sampleRate, format, channelCount,
sampleRate, frameCount, flags, sharedBuffer, output);
format,
channelCount,
frameCount,
((uint16_t)flags) << 16,
sharedBuffer,
output,
&status);
if (track == 0) { if (status != NO_ERROR) {
LOGE("AudioFlinger could not create track, status: %d", status);
return status; return status;
} }
sp<IMemory> cblk = track->getCblk();
if (cblk == 0) {
LOGE("Could not get control block");
return NO_INIT;
}
if (cbf != 0) { if (cbf != 0) {
mAudioTrackThread = new AudioTrackThread(*this, threadCanCallJava); mAudioTrackThread = new AudioTrackThread(*this, threadCanCallJava);
if (mAudioTrackThread == 0) { if (mAudioTrackThread == 0) {
@ -249,22 +232,6 @@ status_t AudioTrack::set(
mStatus = NO_ERROR; mStatus = NO_ERROR;
mAudioTrack = track;
mCblkMemory = cblk;
mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
mCblk->out = 1;
// Update buffer size in case it has been limited by AudioFlinger during track creation
mFrameCount = mCblk->frameCount;
if (sharedBuffer == 0) {
mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
} else {
mCblk->buffers = sharedBuffer->pointer();
// Force buffer full condition as data is already present in shared memory
mCblk->stepUser(mFrameCount);
}
mCblk->volume[0] = mCblk->volume[1] = 0x1000;
mVolume[LEFT] = 1.0f;
mVolume[RIGHT] = 1.0f;
mStreamType = streamType; mStreamType = streamType;
mFormat = format; mFormat = format;
mChannels = channels; mChannels = channels;
@ -351,16 +318,27 @@ void AudioTrack::start()
} }
if (android_atomic_or(1, &mActive) == 0) { if (android_atomic_or(1, &mActive) == 0) {
AudioSystem::startOutput(getOutput(), (AudioSystem::stream_type)mStreamType); audio_io_handle_t output = AudioTrack::getOutput();
mNewPosition = mCblk->server + mUpdatePeriod; status_t status = mAudioTrack->start();
mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS; if (status == DEAD_OBJECT) {
mCblk->waitTimeMs = 0; LOGV("start() dead IAudioTrack: creating a new one");
if (t != 0) { status = createTrack(mStreamType, mCblk->sampleRate, mFormat, mChannelCount,
t->run("AudioTrackThread", THREAD_PRIORITY_AUDIO_CLIENT); mFrameCount, mFlags, mSharedBuffer, output);
} else { }
setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT); if (status == NO_ERROR) {
AudioSystem::startOutput(output, (AudioSystem::stream_type)mStreamType);
mNewPosition = mCblk->server + mUpdatePeriod;
mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
mCblk->waitTimeMs = 0;
if (t != 0) {
t->run("AudioTrackThread", THREAD_PRIORITY_AUDIO_CLIENT);
} else {
setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT);
}
} else {
LOGV("start() failed");
android_atomic_and(~1, &mActive);
} }
mAudioTrack->start();
} }
if (t != 0) { if (t != 0) {
@ -617,10 +595,67 @@ audio_io_handle_t AudioTrack::getOutput()
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
status_t AudioTrack::createTrack(
int streamType,
uint32_t sampleRate,
int format,
int channelCount,
int frameCount,
uint32_t flags,
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output)
{
status_t status;
const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
if (audioFlinger == 0) {
LOGE("Could not get audioflinger");
return NO_INIT;
}
sp<IAudioTrack> track = audioFlinger->createTrack(getpid(),
streamType,
sampleRate,
format,
channelCount,
frameCount,
((uint16_t)flags) << 16,
sharedBuffer,
output,
&status);
if (track == 0) {
LOGE("AudioFlinger could not create track, status: %d", status);
return status;
}
sp<IMemory> cblk = track->getCblk();
if (cblk == 0) {
LOGE("Could not get control block");
return NO_INIT;
}
mAudioTrack.clear();
mAudioTrack = track;
mCblkMemory.clear();
mCblkMemory = cblk;
mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
mCblk->out = 1;
// Update buffer size in case it has been limited by AudioFlinger during track creation
mFrameCount = mCblk->frameCount;
if (sharedBuffer == 0) {
mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
} else {
mCblk->buffers = sharedBuffer->pointer();
// Force buffer full condition as data is already present in shared memory
mCblk->stepUser(mFrameCount);
}
mCblk->volumeLR = (int32_t(int16_t(mVolume[LEFT] * 0x1000)) << 16) | int16_t(mVolume[RIGHT] * 0x1000);
return NO_ERROR;
}
status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
{ {
int active; int active;
int timeout = 0;
status_t result; status_t result;
audio_track_cblk_t* cblk = mCblk; audio_track_cblk_t* cblk = mCblk;
uint32_t framesReq = audioBuffer->frameCount; uint32_t framesReq = audioBuffer->frameCount;
@ -632,17 +667,20 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
uint32_t framesAvail = cblk->framesAvailable(); uint32_t framesAvail = cblk->framesAvailable();
if (framesAvail == 0) { if (framesAvail == 0) {
Mutex::Autolock _l(cblk->lock); cblk->lock.lock();
goto start_loop_here; goto start_loop_here;
while (framesAvail == 0) { while (framesAvail == 0) {
active = mActive; active = mActive;
if (UNLIKELY(!active)) { if (UNLIKELY(!active)) {
LOGV("Not active and NO_MORE_BUFFERS"); LOGV("Not active and NO_MORE_BUFFERS");
cblk->lock.unlock();
return NO_MORE_BUFFERS; return NO_MORE_BUFFERS;
} }
if (UNLIKELY(!waitCount)) if (UNLIKELY(!waitCount)) {
cblk->lock.unlock();
return WOULD_BLOCK; return WOULD_BLOCK;
timeout = 0; }
result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs)); result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs));
if (__builtin_expect(result!=NO_ERROR, false)) { if (__builtin_expect(result!=NO_ERROR, false)) {
cblk->waitTimeMs += waitTimeMs; cblk->waitTimeMs += waitTimeMs;
@ -654,14 +692,23 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
"user=%08x, server=%08x", this, cblk->user, cblk->server); "user=%08x, server=%08x", this, cblk->user, cblk->server);
//unlock cblk mutex before calling mAudioTrack->start() (see issue #1617140) //unlock cblk mutex before calling mAudioTrack->start() (see issue #1617140)
cblk->lock.unlock(); cblk->lock.unlock();
mAudioTrack->start(); result = mAudioTrack->start();
if (result == DEAD_OBJECT) {
LOGW("obtainBuffer() dead IAudioTrack: creating a new one");
result = createTrack(mStreamType, cblk->sampleRate, mFormat, mChannelCount,
mFrameCount, mFlags, mSharedBuffer, getOutput());
if (result == NO_ERROR) {
cblk = mCblk;
cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
}
}
cblk->lock.lock(); cblk->lock.lock();
timeout = 1;
} }
cblk->waitTimeMs = 0; cblk->waitTimeMs = 0;
} }
if (--waitCount == 0) { if (--waitCount == 0) {
cblk->lock.unlock();
return TIMED_OUT; return TIMED_OUT;
} }
} }
@ -669,6 +716,7 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
start_loop_here: start_loop_here:
framesAvail = cblk->framesAvailable_l(); framesAvail = cblk->framesAvailable_l();
} }
cblk->lock.unlock();
} }
cblk->waitTimeMs = 0; cblk->waitTimeMs = 0;
@ -684,11 +732,6 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
framesReq = bufferEnd - u; framesReq = bufferEnd - u;
} }
LOGW_IF(timeout,
"*** SERIOUS WARNING *** obtainBuffer() timed out "
"but didn't need to be locked. We recovered, but "
"this shouldn't happen (user=%08x, server=%08x)", cblk->user, cblk->server);
audioBuffer->flags = mMuted ? Buffer::MUTE : 0; audioBuffer->flags = mMuted ? Buffer::MUTE : 0;
audioBuffer->channelCount = mChannelCount; audioBuffer->channelCount = mChannelCount;
audioBuffer->frameCount = framesReq; audioBuffer->frameCount = framesReq;
@ -991,7 +1034,7 @@ bool audio_track_cblk_t::stepServer(uint32_t frameCount)
// Mark that we have read the first buffer so that next time stepUser() is called // Mark that we have read the first buffer so that next time stepUser() is called
// we switch to normal obtainBuffer() timeout period // we switch to normal obtainBuffer() timeout period
if (bufferTimeoutMs == MAX_STARTUP_TIMEOUT_MS) { if (bufferTimeoutMs == MAX_STARTUP_TIMEOUT_MS) {
bufferTimeoutMs = MAX_RUN_TIMEOUT_MS - 1; bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS - 1;
} }
// It is possible that we receive a flush() // It is possible that we receive a flush()
// while the mixer is processing a block: in this case, // while the mixer is processing a block: in this case,

View File

@ -15,6 +15,10 @@
** limitations under the License. ** limitations under the License.
*/ */
#define LOG_TAG "IAudioRecord"
//#define LOG_NDEBUG 0
#include <utils/Log.h>
#include <stdint.h> #include <stdint.h>
#include <sys/types.h> #include <sys/types.h>
@ -42,8 +46,13 @@ public:
{ {
Parcel data, reply; Parcel data, reply;
data.writeInterfaceToken(IAudioRecord::getInterfaceDescriptor()); data.writeInterfaceToken(IAudioRecord::getInterfaceDescriptor());
remote()->transact(START, data, &reply); status_t status = remote()->transact(START, data, &reply);
return reply.readInt32(); if (status == NO_ERROR) {
status = reply.readInt32();
} else {
LOGW("start() error: %s", strerror(-status));
}
return status;
} }
virtual void stop() virtual void stop()

View File

@ -15,6 +15,10 @@
** limitations under the License. ** limitations under the License.
*/ */
#define LOG_TAG "IAudioTrack"
//#define LOG_NDEBUG 0
#include <utils/Log.h>
#include <stdint.h> #include <stdint.h>
#include <sys/types.h> #include <sys/types.h>
@ -45,8 +49,13 @@ public:
{ {
Parcel data, reply; Parcel data, reply;
data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
remote()->transact(START, data, &reply); status_t status = remote()->transact(START, data, &reply);
return reply.readInt32(); if (status == NO_ERROR) {
status = reply.readInt32();
} else {
LOGW("start() error: %s", strerror(-status));
}
return status;
} }
virtual void stop() virtual void stop()

View File

@ -798,7 +798,7 @@ const unsigned char ToneGenerator::sToneMappingTable[NUM_REGIONS-1][NUM_SUP_TONE
// none // none
// //
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
ToneGenerator::ToneGenerator(int streamType, float volume) { ToneGenerator::ToneGenerator(int streamType, float volume, bool threadCanCallJava) {
LOGV("ToneGenerator constructor: streamType=%d, volume=%f\n", streamType, volume); LOGV("ToneGenerator constructor: streamType=%d, volume=%f\n", streamType, volume);
@ -808,6 +808,7 @@ ToneGenerator::ToneGenerator(int streamType, float volume) {
LOGE("Unable to marshal AudioFlinger"); LOGE("Unable to marshal AudioFlinger");
return; return;
} }
mThreadCanCallJava = threadCanCallJava;
mStreamType = streamType; mStreamType = streamType;
mVolume = volume; mVolume = volume;
mpAudioTrack = 0; mpAudioTrack = 0;
@ -1015,15 +1016,25 @@ bool ToneGenerator::initAudioTrack() {
} }
// Open audio track in mono, PCM 16bit, default sampling rate, default buffer size // Open audio track in mono, PCM 16bit, default sampling rate, default buffer size
mpAudioTrack mpAudioTrack = new AudioTrack();
= new AudioTrack(mStreamType, 0, AudioSystem::PCM_16_BIT, AudioSystem::CHANNEL_OUT_MONO, 0, 0, audioCallback, this, 0);
if (mpAudioTrack == 0) { if (mpAudioTrack == 0) {
LOGE("AudioTrack allocation failed"); LOGE("AudioTrack allocation failed");
goto initAudioTrack_exit; goto initAudioTrack_exit;
} }
LOGV("Create Track: %p\n", mpAudioTrack); LOGV("Create Track: %p\n", mpAudioTrack);
mpAudioTrack->set(mStreamType,
0,
AudioSystem::PCM_16_BIT,
AudioSystem::CHANNEL_OUT_MONO,
0,
0,
audioCallback,
this,
0,
0,
mThreadCanCallJava);
if (mpAudioTrack->initCheck() != NO_ERROR) { if (mpAudioTrack->initCheck() != NO_ERROR) {
LOGE("AudioTrack->initCheck failed"); LOGE("AudioTrack->initCheck failed");
goto initAudioTrack_exit; goto initAudioTrack_exit;