diff options
author | Android (Google) Code Review <android-gerrit@google.com> | 2009-11-05 02:55:26 -0500 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2009-11-05 02:55:26 -0500 |
commit | 67b692920c18f99b096dce285adc6f7439fa866c (patch) | |
tree | e8461fd50578bf3f4ad828fc8ae553893603121f | |
parent | 584bce31b62cdf3efd8a9eb40442c4cc612ce1e6 (diff) | |
parent | bda7469d9b1ec6d9c9d6da40ddf64dc39ff271a9 (diff) | |
download | frameworks_base-67b692920c18f99b096dce285adc6f7439fa866c.zip frameworks_base-67b692920c18f99b096dce285adc6f7439fa866c.tar.gz frameworks_base-67b692920c18f99b096dce285adc6f7439fa866c.tar.bz2 |
Merge change I93f500a5 into eclair
* changes:
Fix issue 2203561: Sholes: audio playing out of earpiece.
-rw-r--r-- | core/jni/android_media_ToneGenerator.cpp | 2 | ||||
-rw-r--r-- | include/media/AudioRecord.h | 6 | ||||
-rw-r--r-- | include/media/AudioTrack.h | 8 | ||||
-rw-r--r-- | include/media/ToneGenerator.h | 3 | ||||
-rw-r--r-- | media/libmedia/AudioRecord.cpp | 127 | ||||
-rw-r--r-- | media/libmedia/AudioTrack.cpp | 163 | ||||
-rw-r--r-- | media/libmedia/IAudioRecord.cpp | 13 | ||||
-rw-r--r-- | media/libmedia/IAudioTrack.cpp | 13 | ||||
-rw-r--r-- | media/libmedia/ToneGenerator.cpp | 19 |
9 files changed, 242 insertions, 112 deletions
diff --git a/core/jni/android_media_ToneGenerator.cpp b/core/jni/android_media_ToneGenerator.cpp index 07bb1ab..50aa967 100644 --- a/core/jni/android_media_ToneGenerator.cpp +++ b/core/jni/android_media_ToneGenerator.cpp @@ -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, 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); diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h index 503cb31..008468c 100644 --- a/include/media/AudioRecord.h +++ b/include/media/AudioRecord.h @@ -314,6 +314,11 @@ private: }; 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<IMemory> mCblkMemory; @@ -341,6 +346,7 @@ private: uint32_t mNewPosition; uint32_t mUpdatePeriod; audio_io_handle_t mInput; + uint32_t mFlags; }; }; // namespace android diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h index 981c2f6..14b30ae 100644 --- a/include/media/AudioTrack.h +++ b/include/media/AudioTrack.h @@ -391,6 +391,14 @@ private: }; 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<IMemory> mCblkMemory; diff --git a/include/media/ToneGenerator.h b/include/media/ToneGenerator.h index c884c2c..1ad1f26 100644 --- a/include/media/ToneGenerator.h +++ b/include/media/ToneGenerator.h @@ -151,7 +151,7 @@ public: NUM_SUP_TONES = LAST_SUP_TONE-FIRST_SUP_TONE+1 }; - ToneGenerator(int streamType, float volume); + ToneGenerator(int streamType, float volume, bool threadCanCallJava = false); ~ToneGenerator(); bool startTone(int toneType, int durationMs = -1); @@ -242,6 +242,7 @@ private: static const ToneDescriptor sToneDescriptors[]; + bool mThreadCanCallJava; unsigned int mTotalSmp; // Total number of audio samples played (gives current time) 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 diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index 5e35564..e63c0d2 100644 --- a/media/libmedia/AudioRecord.cpp +++ b/media/libmedia/AudioRecord.cpp @@ -101,11 +101,6 @@ status_t AudioRecord::set( return INVALID_OPERATION; } - const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); - if (audioFlinger == 0) { - return NO_INIT; - } - if (inputSource == AUDIO_SOURCE_DEFAULT) { inputSource = AUDIO_SOURCE_MIC; } @@ -171,22 +166,14 @@ status_t AudioRecord::set( notificationFrames = frameCount/2; } - // open record channel - status_t status; - 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); + // create the IAudioRecord + status_t status = openRecord(sampleRate, format, channelCount, + frameCount, flags); + + if (status != NO_ERROR) { return status; } - sp<IMemory> cblk = record->getCblk(); - if (cblk == 0) { - return NO_INIT; - } + if (cbf != 0) { mClientRecordThread = new ClientRecordThread(*this, threadCanCallJava); if (mClientRecordThread == 0) { @@ -196,11 +183,6 @@ status_t AudioRecord::set( 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; // Update buffer size in case it has been limited by AudioFlinger during track creation mFrameCount = mCblk->frameCount; @@ -217,6 +199,7 @@ status_t AudioRecord::set( mNewPosition = 0; mUpdatePeriod = 0; mInputSource = (uint8_t)inputSource; + mFlags = flags; return NO_ERROR; } @@ -284,15 +267,26 @@ status_t AudioRecord::start() if (android_atomic_or(1, &mActive) == 0) { ret = AudioSystem::startInput(mInput); 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); + 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 { - setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT); + LOGV("start() failed"); + AudioSystem::stopInput(mInput); + android_atomic_and(~1, &mActive); } - ret = mAudioRecord->start(); } } @@ -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) { int active; - int timeout = 0; status_t result; audio_track_cblk_t* cblk = mCblk; uint32_t framesReq = audioBuffer->frameCount; @@ -411,25 +443,40 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) uint32_t framesReady = cblk->framesReady(); if (framesReady == 0) { - Mutex::Autolock _l(cblk->lock); + cblk->lock.lock(); goto start_loop_here; while (framesReady == 0) { active = mActive; - if (UNLIKELY(!active)) + if (UNLIKELY(!active)) { + cblk->lock.unlock(); return NO_MORE_BUFFERS; - if (UNLIKELY(!waitCount)) + } + if (UNLIKELY(!waitCount)) { + cblk->lock.unlock(); return WOULD_BLOCK; - timeout = 0; + } result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs)); if (__builtin_expect(result!=NO_ERROR, false)) { cblk->waitTimeMs += waitTimeMs; if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) { LOGW( "obtainBuffer timed out (is the CPU pegged?) " "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; } if (--waitCount == 0) { + cblk->lock.unlock(); return TIMED_OUT; } } @@ -437,13 +484,9 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) start_loop_here: 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; if (framesReq > framesReady) { diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index 4b9d272..8529a8e 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -122,11 +122,6 @@ status_t AudioTrack::set( return INVALID_OPERATION; } - const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); - if (audioFlinger == 0) { - LOGE("Could not get audioflinger"); - return NO_INIT; - } int afSampleRate; if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) { return NO_INIT; @@ -217,28 +212,16 @@ status_t AudioTrack::set( } } - // create the track - status_t status; - sp<IAudioTrack> track = audioFlinger->createTrack(getpid(), - streamType, - sampleRate, - format, - channelCount, - frameCount, - ((uint16_t)flags) << 16, - sharedBuffer, - output, - &status); + mVolume[LEFT] = 1.0f; + mVolume[RIGHT] = 1.0f; + // create the IAudioTrack + status_t status = createTrack(streamType, sampleRate, format, channelCount, + frameCount, flags, sharedBuffer, output); - if (track == 0) { - LOGE("AudioFlinger could not create track, status: %d", status); + if (status != NO_ERROR) { return status; } - sp<IMemory> cblk = track->getCblk(); - if (cblk == 0) { - LOGE("Could not get control block"); - return NO_INIT; - } + if (cbf != 0) { mAudioTrackThread = new AudioTrackThread(*this, threadCanCallJava); if (mAudioTrackThread == 0) { @@ -249,22 +232,6 @@ status_t AudioTrack::set( 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; mFormat = format; mChannels = channels; @@ -351,16 +318,27 @@ void AudioTrack::start() } if (android_atomic_or(1, &mActive) == 0) { - AudioSystem::startOutput(getOutput(), (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); + audio_io_handle_t output = AudioTrack::getOutput(); + status_t status = mAudioTrack->start(); + if (status == DEAD_OBJECT) { + LOGV("start() dead IAudioTrack: creating a new one"); + status = createTrack(mStreamType, mCblk->sampleRate, mFormat, mChannelCount, + mFrameCount, mFlags, mSharedBuffer, output); + } + 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 { - setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT); + LOGV("start() failed"); + android_atomic_and(~1, &mActive); } - mAudioTrack->start(); } 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) { int active; - int timeout = 0; status_t result; audio_track_cblk_t* cblk = mCblk; uint32_t framesReq = audioBuffer->frameCount; @@ -632,17 +667,20 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) uint32_t framesAvail = cblk->framesAvailable(); if (framesAvail == 0) { - Mutex::Autolock _l(cblk->lock); + cblk->lock.lock(); goto start_loop_here; while (framesAvail == 0) { active = mActive; if (UNLIKELY(!active)) { LOGV("Not active and NO_MORE_BUFFERS"); + cblk->lock.unlock(); return NO_MORE_BUFFERS; } - if (UNLIKELY(!waitCount)) + if (UNLIKELY(!waitCount)) { + cblk->lock.unlock(); return WOULD_BLOCK; - timeout = 0; + } + result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs)); if (__builtin_expect(result!=NO_ERROR, false)) { 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); //unlock cblk mutex before calling mAudioTrack->start() (see issue #1617140) 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(); - timeout = 1; } cblk->waitTimeMs = 0; } if (--waitCount == 0) { + cblk->lock.unlock(); return TIMED_OUT; } } @@ -669,6 +716,7 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) start_loop_here: framesAvail = cblk->framesAvailable_l(); } + cblk->lock.unlock(); } cblk->waitTimeMs = 0; @@ -684,11 +732,6 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) 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->channelCount = mChannelCount; 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 // we switch to normal obtainBuffer() timeout period 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() // while the mixer is processing a block: in this case, diff --git a/media/libmedia/IAudioRecord.cpp b/media/libmedia/IAudioRecord.cpp index dacf75a..ba0d55b 100644 --- a/media/libmedia/IAudioRecord.cpp +++ b/media/libmedia/IAudioRecord.cpp @@ -15,6 +15,10 @@ ** limitations under the License. */ +#define LOG_TAG "IAudioRecord" +//#define LOG_NDEBUG 0 +#include <utils/Log.h> + #include <stdint.h> #include <sys/types.h> @@ -42,8 +46,13 @@ public: { Parcel data, reply; data.writeInterfaceToken(IAudioRecord::getInterfaceDescriptor()); - remote()->transact(START, data, &reply); - return reply.readInt32(); + status_t status = remote()->transact(START, data, &reply); + if (status == NO_ERROR) { + status = reply.readInt32(); + } else { + LOGW("start() error: %s", strerror(-status)); + } + return status; } virtual void stop() diff --git a/media/libmedia/IAudioTrack.cpp b/media/libmedia/IAudioTrack.cpp index 7f43347..01ffd75 100644 --- a/media/libmedia/IAudioTrack.cpp +++ b/media/libmedia/IAudioTrack.cpp @@ -15,6 +15,10 @@ ** limitations under the License. */ +#define LOG_TAG "IAudioTrack" +//#define LOG_NDEBUG 0 +#include <utils/Log.h> + #include <stdint.h> #include <sys/types.h> @@ -45,8 +49,13 @@ public: { Parcel data, reply; data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); - remote()->transact(START, data, &reply); - return reply.readInt32(); + status_t status = remote()->transact(START, data, &reply); + if (status == NO_ERROR) { + status = reply.readInt32(); + } else { + LOGW("start() error: %s", strerror(-status)); + } + return status; } virtual void stop() diff --git a/media/libmedia/ToneGenerator.cpp b/media/libmedia/ToneGenerator.cpp index 91d0d00..60e3d71 100644 --- a/media/libmedia/ToneGenerator.cpp +++ b/media/libmedia/ToneGenerator.cpp @@ -798,7 +798,7 @@ const unsigned char ToneGenerator::sToneMappingTable[NUM_REGIONS-1][NUM_SUP_TONE // 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); @@ -808,6 +808,7 @@ ToneGenerator::ToneGenerator(int streamType, float volume) { LOGE("Unable to marshal AudioFlinger"); return; } + mThreadCanCallJava = threadCanCallJava; mStreamType = streamType; mVolume = volume; mpAudioTrack = 0; @@ -1015,15 +1016,25 @@ bool ToneGenerator::initAudioTrack() { } // Open audio track in mono, PCM 16bit, default sampling rate, default buffer size - mpAudioTrack - = new AudioTrack(mStreamType, 0, AudioSystem::PCM_16_BIT, AudioSystem::CHANNEL_OUT_MONO, 0, 0, audioCallback, this, 0); - + mpAudioTrack = new AudioTrack(); if (mpAudioTrack == 0) { LOGE("AudioTrack allocation failed"); goto initAudioTrack_exit; } 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) { LOGE("AudioTrack->initCheck failed"); goto initAudioTrack_exit; |