diff options
author | Eric Laurent <elaurent@google.com> | 2010-06-04 00:18:07 -0700 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2010-06-04 00:18:07 -0700 |
commit | 4b18200b9cc97d22ac4b77634195ec5f48004568 (patch) | |
tree | a7aff5ca9f0c6a651a483f7a9f44614cda67c43e /media/libmedia | |
parent | 77205ace4efeac3be306fff6299263cdb7bdd3ae (diff) | |
parent | 030a15531c200247e81d36f13f81d6ee443ea81b (diff) | |
download | frameworks_base-4b18200b9cc97d22ac4b77634195ec5f48004568.zip frameworks_base-4b18200b9cc97d22ac4b77634195ec5f48004568.tar.gz frameworks_base-4b18200b9cc97d22ac4b77634195ec5f48004568.tar.bz2 |
am 030a1553: am 2ea200c5: Merge "Issue 2667801: [Audio Effect Framework] AudioFlinger, AudioMixer AudioTrack modifications." into kraken
Diffstat (limited to 'media/libmedia')
-rw-r--r-- | media/libmedia/AudioRecord.cpp | 21 | ||||
-rw-r--r-- | media/libmedia/AudioSystem.cpp | 6 | ||||
-rw-r--r-- | media/libmedia/AudioTrack.cpp | 66 | ||||
-rw-r--r-- | media/libmedia/IAudioFlinger.cpp | 260 | ||||
-rw-r--r-- | media/libmedia/IAudioTrack.cpp | 24 |
5 files changed, 358 insertions, 19 deletions
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index fd2b1ce..a2436ab 100644 --- a/media/libmedia/AudioRecord.cpp +++ b/media/libmedia/AudioRecord.cpp @@ -45,7 +45,7 @@ namespace android { // --------------------------------------------------------------------------- AudioRecord::AudioRecord() - : mStatus(NO_INIT) + : mStatus(NO_INIT), mSessionId(0) { } @@ -58,11 +58,12 @@ AudioRecord::AudioRecord( uint32_t flags, callback_t cbf, void* user, - int notificationFrames) - : mStatus(NO_INIT) + int notificationFrames, + int sessionId) + : mStatus(NO_INIT), mSessionId(0) { mStatus = set(inputSource, sampleRate, format, channels, - frameCount, flags, cbf, user, notificationFrames); + frameCount, flags, cbf, user, notificationFrames, sessionId); } AudioRecord::~AudioRecord() @@ -91,7 +92,8 @@ status_t AudioRecord::set( callback_t cbf, void* user, int notificationFrames, - bool threadCanCallJava) + bool threadCanCallJava, + int sessionId) { LOGV("set(): sampleRate %d, channels %d, frameCount %d",sampleRate, channels, frameCount); @@ -119,6 +121,7 @@ status_t AudioRecord::set( if (!AudioSystem::isInputChannel(channels)) { return BAD_VALUE; } + int channelCount = AudioSystem::popCount(channels); audio_io_handle_t input = AudioSystem::getInput(inputSource, @@ -164,6 +167,8 @@ status_t AudioRecord::set( notificationFrames = frameCount/2; } + mSessionId = sessionId; + // create the IAudioRecord status_t status = openRecord(sampleRate, format, channelCount, frameCount, flags, input); @@ -414,6 +419,7 @@ status_t AudioRecord::openRecord( channelCount, frameCount, ((uint16_t)flags) << 16, + &mSessionId, &status); if (record == 0) { LOGE("AudioFlinger could not create record track, status: %d", status); @@ -532,6 +538,11 @@ audio_io_handle_t AudioRecord::getInput() return mInput; } +int AudioRecord::getSessionId() +{ + return mSessionId; +} + // ------------------------------------------------------------------------- ssize_t AudioRecord::read(void* buffer, size_t userSize) diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp index 4478abd..372a927 100644 --- a/media/libmedia/AudioSystem.cpp +++ b/media/libmedia/AudioSystem.cpp @@ -364,6 +364,12 @@ unsigned int AudioSystem::getInputFramesLost(audio_io_handle_t ioHandle) { return result; } +int AudioSystem::newAudioSessionId() { + const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); + if (af == 0) return 0; + return af->newAudioSessionId(); +} + // --------------------------------------------------------------------------- void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who) { diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index c350532..4b61131 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -58,7 +58,8 @@ AudioTrack::AudioTrack( uint32_t flags, callback_t cbf, void* user, - int notificationFrames) + int notificationFrames, + int sessionId) : mStatus(NO_INIT) { mStatus = set(streamType, sampleRate, format, channels, @@ -74,7 +75,8 @@ AudioTrack::AudioTrack( uint32_t flags, callback_t cbf, void* user, - int notificationFrames) + int notificationFrames, + int sessionId) : mStatus(NO_INIT) { mStatus = set(streamType, sampleRate, format, channels, @@ -110,7 +112,8 @@ status_t AudioTrack::set( void* user, int notificationFrames, const sp<IMemory>& sharedBuffer, - bool threadCanCallJava) + bool threadCanCallJava, + int sessionId) { LOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size()); @@ -171,8 +174,11 @@ status_t AudioTrack::set( mVolume[LEFT] = 1.0f; mVolume[RIGHT] = 1.0f; + mSendLevel = 0; mFrameCount = frameCount; mNotificationFramesReq = notificationFrames; + mSessionId = sessionId; + // create the IAudioTrack status_t status = createTrack(streamType, sampleRate, format, channelCount, frameCount, flags, sharedBuffer, output, true); @@ -396,19 +402,49 @@ bool AudioTrack::muted() const return mMuted; } -void AudioTrack::setVolume(float left, float right) +status_t AudioTrack::setVolume(float left, float right) { + if (left > 1.0f || right > 1.0f) { + return BAD_VALUE; + } + mVolume[LEFT] = left; mVolume[RIGHT] = right; // write must be atomic - mCblk->volumeLR = (int32_t(int16_t(left * 0x1000)) << 16) | int16_t(right * 0x1000); + mCblk->volumeLR = (uint32_t(uint16_t(right * 0x1000)) << 16) | uint16_t(left * 0x1000); + + return NO_ERROR; } void AudioTrack::getVolume(float* left, float* right) { - *left = mVolume[LEFT]; - *right = mVolume[RIGHT]; + if (left != NULL) { + *left = mVolume[LEFT]; + } + if (right != NULL) { + *right = mVolume[RIGHT]; + } +} + +status_t AudioTrack::setSendLevel(float level) +{ + if (level > 1.0f) { + return BAD_VALUE; + } + + mSendLevel = level; + + mCblk->sendLevel = uint16_t(level * 0x1000); + + return NO_ERROR; +} + +void AudioTrack::getSendLevel(float* level) +{ + if (level != NULL) { + *level = mSendLevel; + } } status_t AudioTrack::setSampleRate(int rate) @@ -563,6 +599,16 @@ audio_io_handle_t AudioTrack::getOutput() mCblk->sampleRate, mFormat, mChannels, (AudioSystem::output_flags)mFlags); } +int AudioTrack::getSessionId() +{ + return mSessionId; +} + +status_t AudioTrack::attachAuxEffect(int effectId) +{ + return mAudioTrack->attachAuxEffect(effectId); +} + // ------------------------------------------------------------------------- status_t AudioTrack::createTrack( @@ -647,6 +693,7 @@ status_t AudioTrack::createTrack( ((uint16_t)flags) << 16, sharedBuffer, output, + &mSessionId, &status); if (track == 0) { @@ -672,7 +719,8 @@ status_t AudioTrack::createTrack( mCblk->stepUser(mCblk->frameCount); } - mCblk->volumeLR = (int32_t(int16_t(mVolume[LEFT] * 0x1000)) << 16) | int16_t(mVolume[RIGHT] * 0x1000); + mCblk->volumeLR = (uint32_t(uint16_t(mVolume[RIGHT] * 0x1000)) << 16) | uint16_t(mVolume[LEFT] * 0x1000); + mCblk->sendLevel = uint16_t(mSendLevel * 0x1000); mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS; mCblk->waitTimeMs = 0; mRemainingFrames = mNotificationFramesAct; @@ -1016,7 +1064,7 @@ audio_track_cblk_t::audio_track_cblk_t() : lock(Mutex::SHARED), cv(Condition::SHARED), user(0), server(0), userBase(0), serverBase(0), buffers(0), frameCount(0), loopStart(UINT_MAX), loopEnd(UINT_MAX), loopCount(0), volumeLR(0), - flags(0) + flags(0), sendLevel(0) { } diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp index 47bcc12..f2a8db3 100644 --- a/media/libmedia/IAudioFlinger.cpp +++ b/media/libmedia/IAudioFlinger.cpp @@ -62,7 +62,14 @@ enum { SET_STREAM_OUTPUT, SET_VOICE_VOLUME, GET_RENDER_POSITION, - GET_INPUT_FRAMES_LOST + GET_INPUT_FRAMES_LOST, + NEW_AUDIO_SESSION_ID, + LOAD_EFFECT_LIBRARY, + UNLOAD_EFFECT_LIBRARY, + QUERY_NUM_EFFECTS, + QUERY_NEXT_EFFECT, + GET_EFFECT_DESCRIPTOR, + CREATE_EFFECT }; class BpAudioFlinger : public BpInterface<IAudioFlinger> @@ -83,6 +90,7 @@ public: uint32_t flags, const sp<IMemory>& sharedBuffer, int output, + int *sessionId, status_t *status) { Parcel data, reply; @@ -97,10 +105,19 @@ public: data.writeInt32(flags); data.writeStrongBinder(sharedBuffer->asBinder()); data.writeInt32(output); + int lSessionId = 0; + if (sessionId != NULL) { + lSessionId = *sessionId; + } + data.writeInt32(lSessionId); status_t lStatus = remote()->transact(CREATE_TRACK, data, &reply); if (lStatus != NO_ERROR) { LOGE("createTrack error: %s", strerror(-lStatus)); } else { + lSessionId = reply.readInt32(); + if (sessionId != NULL) { + *sessionId = lSessionId; + } lStatus = reply.readInt32(); track = interface_cast<IAudioTrack>(reply.readStrongBinder()); } @@ -118,6 +135,7 @@ public: int channelCount, int frameCount, uint32_t flags, + int *sessionId, status_t *status) { Parcel data, reply; @@ -130,10 +148,19 @@ public: data.writeInt32(channelCount); data.writeInt32(frameCount); data.writeInt32(flags); + int lSessionId = 0; + if (sessionId != NULL) { + lSessionId = *sessionId; + } + data.writeInt32(lSessionId); status_t lStatus = remote()->transact(OPEN_RECORD, data, &reply); if (lStatus != NO_ERROR) { LOGE("openRecord error: %s", strerror(-lStatus)); } else { + lSessionId = reply.readInt32(); + if (sessionId != NULL) { + *sessionId = lSessionId; + } lStatus = reply.readInt32(); record = interface_cast<IAudioRecord>(reply.readStrongBinder()); } @@ -497,6 +524,157 @@ public: remote()->transact(GET_INPUT_FRAMES_LOST, data, &reply); return reply.readInt32(); } + + virtual int newAudioSessionId() + { + Parcel data, reply; + data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); + status_t status = remote()->transact(NEW_AUDIO_SESSION_ID, data, &reply); + int id = 0; + if (status == NO_ERROR) { + id = reply.readInt32(); + } + return id; + } + + virtual status_t loadEffectLibrary(const char *libPath, int *handle) + { + if (libPath == NULL || handle == NULL) { + return BAD_VALUE; + } + *handle = 0; + Parcel data, reply; + data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); + data.writeCString(libPath); + status_t status = remote()->transact(LOAD_EFFECT_LIBRARY, data, &reply); + if (status == NO_ERROR) { + status = reply.readInt32(); + if (status == NO_ERROR) { + *handle = reply.readInt32(); + } + } + return status; + } + + virtual status_t unloadEffectLibrary(int handle) + { + Parcel data, reply; + data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); + data.writeInt32(handle); + status_t status = remote()->transact(UNLOAD_EFFECT_LIBRARY, data, &reply); + if (status == NO_ERROR) { + status = reply.readInt32(); + } + return status; + } + + virtual status_t queryNumberEffects(uint32_t *numEffects) + { + Parcel data, reply; + data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); + status_t status = remote()->transact(QUERY_NUM_EFFECTS, data, &reply); + if (status != NO_ERROR) { + return status; + } + status = reply.readInt32(); + if (status != NO_ERROR) { + return status; + } + if (numEffects) { + *numEffects = (uint32_t)reply.readInt32(); + } + return NO_ERROR; + } + + virtual status_t queryNextEffect(effect_descriptor_t *pDescriptor) + { + if (pDescriptor == NULL) { + return BAD_VALUE; + } + Parcel data, reply; + data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); + status_t status = remote()->transact(QUERY_NEXT_EFFECT, data, &reply); + if (status != NO_ERROR) { + return status; + } + status = reply.readInt32(); + if (status != NO_ERROR) { + return status; + } + reply.read(pDescriptor, sizeof(effect_descriptor_t)); + return NO_ERROR; + } + + virtual status_t getEffectDescriptor(effect_uuid_t *pUuid, effect_descriptor_t *pDescriptor) + { + if (pUuid == NULL || pDescriptor == NULL) { + return BAD_VALUE; + } + Parcel data, reply; + data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); + data.write(pUuid, sizeof(effect_uuid_t)); + status_t status = remote()->transact(GET_EFFECT_DESCRIPTOR, data, &reply); + if (status != NO_ERROR) { + return status; + } + status = reply.readInt32(); + if (status != NO_ERROR) { + return status; + } + reply.read(pDescriptor, sizeof(effect_descriptor_t)); + return NO_ERROR; + } + + virtual sp<IEffect> createEffect(pid_t pid, + effect_descriptor_t *pDesc, + const sp<IEffectClient>& client, + int32_t priority, + int output, + int sessionId, + status_t *status, + int *id, + int *enabled) + { + Parcel data, reply; + sp<IEffect> effect; + + if (pDesc == NULL) { + return effect; + if (status) { + *status = BAD_VALUE; + } + } + + data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); + data.writeInt32(pid); + data.write(pDesc, sizeof(effect_descriptor_t)); + data.writeStrongBinder(client->asBinder()); + data.writeInt32(priority); + data.writeInt32(output); + data.writeInt32(sessionId); + + status_t lStatus = remote()->transact(CREATE_EFFECT, data, &reply); + if (lStatus != NO_ERROR) { + LOGE("createEffect error: %s", strerror(-lStatus)); + } else { + lStatus = reply.readInt32(); + int tmp = reply.readInt32(); + if (id) { + *id = tmp; + } + tmp = reply.readInt32(); + if (enabled) { + *enabled = tmp; + } + effect = interface_cast<IEffect>(reply.readStrongBinder()); + reply.read(pDesc, sizeof(effect_descriptor_t)); + } + if (status) { + *status = lStatus; + } + + return effect; + } }; IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger"); @@ -518,10 +696,12 @@ status_t BnAudioFlinger::onTransact( uint32_t flags = data.readInt32(); sp<IMemory> buffer = interface_cast<IMemory>(data.readStrongBinder()); int output = data.readInt32(); + int sessionId = data.readInt32(); status_t status; sp<IAudioTrack> track = createTrack(pid, streamType, sampleRate, format, - channelCount, bufferCount, flags, buffer, output, &status); + channelCount, bufferCount, flags, buffer, output, &sessionId, &status); + reply->writeInt32(sessionId); reply->writeInt32(status); reply->writeStrongBinder(track->asBinder()); return NO_ERROR; @@ -535,9 +715,11 @@ status_t BnAudioFlinger::onTransact( int channelCount = data.readInt32(); size_t bufferCount = data.readInt32(); uint32_t flags = data.readInt32(); + int sessionId = data.readInt32(); status_t status; sp<IAudioRecord> record = openRecord(pid, input, - sampleRate, format, channelCount, bufferCount, flags, &status); + sampleRate, format, channelCount, bufferCount, flags, &sessionId, &status); + reply->writeInt32(sessionId); reply->writeInt32(status); reply->writeStrongBinder(record->asBinder()); return NO_ERROR; @@ -768,7 +950,79 @@ status_t BnAudioFlinger::onTransact( reply->writeInt32(getInputFramesLost(ioHandle)); return NO_ERROR; } break; + case NEW_AUDIO_SESSION_ID: { + CHECK_INTERFACE(IAudioFlinger, data, reply); + reply->writeInt32(newAudioSessionId()); + return NO_ERROR; + } break; + case LOAD_EFFECT_LIBRARY: { + CHECK_INTERFACE(IAudioFlinger, data, reply); + int handle; + status_t status = loadEffectLibrary(data.readCString(), &handle); + reply->writeInt32(status); + if (status == NO_ERROR) { + reply->writeInt32(handle); + } + return NO_ERROR; + } + case UNLOAD_EFFECT_LIBRARY: { + CHECK_INTERFACE(IAudioFlinger, data, reply); + reply->writeInt32(unloadEffectLibrary(data.readInt32())); + return NO_ERROR; + } + case QUERY_NUM_EFFECTS: { + CHECK_INTERFACE(IAudioFlinger, data, reply); + uint32_t numEffects; + status_t status = queryNumberEffects(&numEffects); + reply->writeInt32(status); + if (status == NO_ERROR) { + reply->writeInt32((int32_t)numEffects); + } + return NO_ERROR; + } + case QUERY_NEXT_EFFECT: { + CHECK_INTERFACE(IAudioFlinger, data, reply); + effect_descriptor_t desc; + status_t status = queryNextEffect(&desc); + reply->writeInt32(status); + if (status == NO_ERROR) { + reply->write(&desc, sizeof(effect_descriptor_t)); + } + return NO_ERROR; + } + case GET_EFFECT_DESCRIPTOR: { + CHECK_INTERFACE(IAudioFlinger, data, reply); + effect_uuid_t uuid; + data.read(&uuid, sizeof(effect_uuid_t)); + effect_descriptor_t desc; + status_t status = getEffectDescriptor(&uuid, &desc); + reply->writeInt32(status); + if (status == NO_ERROR) { + reply->write(&desc, sizeof(effect_descriptor_t)); + } + return NO_ERROR; + } + case CREATE_EFFECT: { + CHECK_INTERFACE(IAudioFlinger, data, reply); + pid_t pid = data.readInt32(); + effect_descriptor_t desc; + data.read(&desc, sizeof(effect_descriptor_t)); + sp<IEffectClient> client = interface_cast<IEffectClient>(data.readStrongBinder()); + int32_t priority = data.readInt32(); + int output = data.readInt32(); + int sessionId = data.readInt32(); + status_t status; + int id; + int enabled; + sp<IEffect> effect = createEffect(pid, &desc, client, priority, output, sessionId, &status, &id, &enabled); + reply->writeInt32(status); + reply->writeInt32(id); + reply->writeInt32(enabled); + reply->writeStrongBinder(effect->asBinder()); + reply->write(&desc, sizeof(effect_descriptor_t)); + return NO_ERROR; + } break; default: return BBinder::onTransact(code, data, reply, flags); } diff --git a/media/libmedia/IAudioTrack.cpp b/media/libmedia/IAudioTrack.cpp index 01ffd75..bc8ff34 100644 --- a/media/libmedia/IAudioTrack.cpp +++ b/media/libmedia/IAudioTrack.cpp @@ -34,7 +34,8 @@ enum { STOP, FLUSH, MUTE, - PAUSE + PAUSE, + ATTACH_AUX_EFFECT }; class BpAudioTrack : public BpInterface<IAudioTrack> @@ -97,7 +98,21 @@ public: cblk = interface_cast<IMemory>(reply.readStrongBinder()); } return cblk; - } + } + + virtual status_t attachAuxEffect(int effectId) + { + Parcel data, reply; + data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); + data.writeInt32(effectId); + status_t status = remote()->transact(ATTACH_AUX_EFFECT, data, &reply); + if (status == NO_ERROR) { + status = reply.readInt32(); + } else { + LOGW("attachAuxEffect() error: %s", strerror(-status)); + } + return status; + } }; IMPLEMENT_META_INTERFACE(AudioTrack, "android.media.IAudioTrack"); @@ -138,6 +153,11 @@ status_t BnAudioTrack::onTransact( pause(); return NO_ERROR; } + case ATTACH_AUX_EFFECT: { + CHECK_INTERFACE(IAudioTrack, data, reply); + reply->writeInt32(attachAuxEffect(data.readInt32())); + return NO_ERROR; + } break; default: return BBinder::onTransact(code, data, reply, flags); } |