Merge change Icf10db28 into eclair

* changes:
  Fix issue 2192181: AudioFlinger must provide separated methods to set VOICE_CALL stream volume and down link audio volume.
This commit is contained in:
Android (Google) Code Review
2009-10-24 04:32:28 -04:00
8 changed files with 102 additions and 37 deletions

View File

@@ -220,6 +220,7 @@ public:
static status_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount, static status_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount,
size_t* buffSize); size_t* buffSize);
static status_t setVoiceVolume(float volume);
// //
// AudioPolicyService interface // AudioPolicyService interface

View File

@@ -128,6 +128,8 @@ public:
virtual status_t closeInput(int input) = 0; virtual status_t closeInput(int input) = 0;
virtual status_t setStreamOutput(uint32_t stream, int output) = 0; virtual status_t setStreamOutput(uint32_t stream, int output) = 0;
virtual status_t setVoiceVolume(float volume) = 0;
}; };

View File

@@ -482,38 +482,17 @@ status_t AudioFlinger::setStreamVolume(int stream, float value, int output)
} }
} }
status_t ret = NO_ERROR;
if (stream == AudioSystem::VOICE_CALL ||
stream == AudioSystem::BLUETOOTH_SCO) {
float hwValue;
if (stream == AudioSystem::VOICE_CALL) {
hwValue = (float)AudioSystem::logToLinear(value)/100.0f;
// offset value to reflect actual hardware volume that never reaches 0
// 1% corresponds roughly to first step in VOICE_CALL stream volume setting (see AudioService.java)
value = 0.01 + 0.99 * value;
} else { // (type == AudioSystem::BLUETOOTH_SCO)
hwValue = 1.0f;
}
AutoMutex lock(mHardwareLock);
mHardwareStatus = AUDIO_SET_VOICE_VOLUME;
ret = mAudioHardware->setVoiceVolume(hwValue);
mHardwareStatus = AUDIO_HW_IDLE;
}
mStreamTypes[stream].volume = value; mStreamTypes[stream].volume = value;
if (thread == NULL) { if (thread == NULL) {
for (uint32_t i = 0; i < mPlaybackThreads.size(); i++) for (uint32_t i = 0; i < mPlaybackThreads.size(); i++) {
mPlaybackThreads.valueAt(i)->setStreamVolume(stream, value); mPlaybackThreads.valueAt(i)->setStreamVolume(stream, value);
}
} else { } else {
thread->setStreamVolume(stream, value); thread->setStreamVolume(stream, value);
} }
return ret; return NO_ERROR;
} }
status_t AudioFlinger::setStreamMute(int stream, bool muted) status_t AudioFlinger::setStreamMute(int stream, bool muted)
@@ -553,11 +532,6 @@ float AudioFlinger::streamVolume(int stream, int output) const
volume = mStreamTypes[stream].volume; volume = mStreamTypes[stream].volume;
} }
// remove correction applied by setStreamVolume()
if (stream == AudioSystem::VOICE_CALL) {
volume = (volume - 0.01) / 0.99 ;
}
return volume; return volume;
} }
@@ -644,6 +618,21 @@ size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, int format, int cha
return mAudioHardware->getInputBufferSize(sampleRate, format, channelCount); return mAudioHardware->getInputBufferSize(sampleRate, format, channelCount);
} }
status_t AudioFlinger::setVoiceVolume(float value)
{
// check calling permissions
if (!settingsAllowed()) {
return PERMISSION_DENIED;
}
AutoMutex lock(mHardwareLock);
mHardwareStatus = AUDIO_SET_VOICE_VOLUME;
status_t ret = mAudioHardware->setVoiceVolume(value);
mHardwareStatus = AUDIO_HW_IDLE;
return ret;
}
void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client) void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)
{ {

View File

@@ -133,6 +133,8 @@ public:
virtual status_t setStreamOutput(uint32_t stream, int output); virtual status_t setStreamOutput(uint32_t stream, int output);
virtual status_t setVoiceVolume(float volume);
// IBinder::DeathRecipient // IBinder::DeathRecipient
virtual void binderDied(const wp<IBinder>& who); virtual void binderDied(const wp<IBinder>& who);

View File

@@ -495,6 +495,10 @@ status_t AudioPolicyService::stopTone()
return NO_ERROR; return NO_ERROR;
} }
status_t AudioPolicyService::setVoiceVolume(float volume, int delayMs)
{
return mAudioCommandThread->voiceVolumeCommand(volume, delayMs);
}
// ----------- AudioPolicyService::AudioCommandThread implementation ---------- // ----------- AudioPolicyService::AudioCommandThread implementation ----------
@@ -577,6 +581,16 @@ bool AudioPolicyService::AudioCommandThread::threadLoop()
} }
delete data; delete data;
}break; }break;
case SET_VOICE_VOLUME: {
VoiceVolumeData *data = (VoiceVolumeData *)command->mParam;
LOGV("AudioCommandThread() processing set voice volume volume %f", data->mVolume);
command->mStatus = AudioSystem::setVoiceVolume(data->mVolume);
if (command->mWaitStatus) {
command->mCond.signal();
mWaitWorkCV.wait(mLock);
}
delete data;
}break;
default: default:
LOGW("AudioCommandThread() unknown command %d", command->mCommand); LOGW("AudioCommandThread() unknown command %d", command->mCommand);
} }
@@ -597,7 +611,6 @@ bool AudioPolicyService::AudioCommandThread::threadLoop()
void AudioPolicyService::AudioCommandThread::startToneCommand(int type, int stream) void AudioPolicyService::AudioCommandThread::startToneCommand(int type, int stream)
{ {
Mutex::Autolock _l(mLock);
AudioCommand *command = new AudioCommand(); AudioCommand *command = new AudioCommand();
command->mCommand = START_TONE; command->mCommand = START_TONE;
ToneData *data = new ToneData(); ToneData *data = new ToneData();
@@ -605,6 +618,7 @@ void AudioPolicyService::AudioCommandThread::startToneCommand(int type, int stre
data->mStream = stream; data->mStream = stream;
command->mParam = (void *)data; command->mParam = (void *)data;
command->mWaitStatus = false; command->mWaitStatus = false;
Mutex::Autolock _l(mLock);
insertCommand_l(command); insertCommand_l(command);
LOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream); LOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream);
mWaitWorkCV.signal(); mWaitWorkCV.signal();
@@ -612,11 +626,11 @@ void AudioPolicyService::AudioCommandThread::startToneCommand(int type, int stre
void AudioPolicyService::AudioCommandThread::stopToneCommand() void AudioPolicyService::AudioCommandThread::stopToneCommand()
{ {
Mutex::Autolock _l(mLock);
AudioCommand *command = new AudioCommand(); AudioCommand *command = new AudioCommand();
command->mCommand = STOP_TONE; command->mCommand = STOP_TONE;
command->mParam = NULL; command->mParam = NULL;
command->mWaitStatus = false; command->mWaitStatus = false;
Mutex::Autolock _l(mLock);
insertCommand_l(command); insertCommand_l(command);
LOGV("AudioCommandThread() adding tone stop"); LOGV("AudioCommandThread() adding tone stop");
mWaitWorkCV.signal(); mWaitWorkCV.signal();
@@ -626,7 +640,6 @@ status_t AudioPolicyService::AudioCommandThread::volumeCommand(int stream, float
{ {
status_t status = NO_ERROR; status_t status = NO_ERROR;
Mutex::Autolock _l(mLock);
AudioCommand *command = new AudioCommand(); AudioCommand *command = new AudioCommand();
command->mCommand = SET_VOLUME; command->mCommand = SET_VOLUME;
VolumeData *data = new VolumeData(); VolumeData *data = new VolumeData();
@@ -639,6 +652,7 @@ status_t AudioPolicyService::AudioCommandThread::volumeCommand(int stream, float
} else { } else {
command->mWaitStatus = false; command->mWaitStatus = false;
} }
Mutex::Autolock _l(mLock);
insertCommand_l(command, delayMs); insertCommand_l(command, delayMs);
LOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d", stream, volume, output); LOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d", stream, volume, output);
mWaitWorkCV.signal(); mWaitWorkCV.signal();
@@ -654,7 +668,6 @@ status_t AudioPolicyService::AudioCommandThread::parametersCommand(int ioHandle,
{ {
status_t status = NO_ERROR; status_t status = NO_ERROR;
Mutex::Autolock _l(mLock);
AudioCommand *command = new AudioCommand(); AudioCommand *command = new AudioCommand();
command->mCommand = SET_PARAMETERS; command->mCommand = SET_PARAMETERS;
ParametersData *data = new ParametersData(); ParametersData *data = new ParametersData();
@@ -666,6 +679,7 @@ status_t AudioPolicyService::AudioCommandThread::parametersCommand(int ioHandle,
} else { } else {
command->mWaitStatus = false; command->mWaitStatus = false;
} }
Mutex::Autolock _l(mLock);
insertCommand_l(command, delayMs); insertCommand_l(command, delayMs);
LOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d", keyValuePairs.string(), ioHandle, delayMs); LOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d", keyValuePairs.string(), ioHandle, delayMs);
mWaitWorkCV.signal(); mWaitWorkCV.signal();
@@ -677,6 +691,32 @@ status_t AudioPolicyService::AudioCommandThread::parametersCommand(int ioHandle,
return status; return status;
} }
status_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs)
{
status_t status = NO_ERROR;
AudioCommand *command = new AudioCommand();
command->mCommand = SET_VOICE_VOLUME;
VoiceVolumeData *data = new VoiceVolumeData();
data->mVolume = volume;
command->mParam = data;
if (delayMs == 0) {
command->mWaitStatus = true;
} else {
command->mWaitStatus = false;
}
Mutex::Autolock _l(mLock);
insertCommand_l(command, delayMs);
LOGV("AudioCommandThread() adding set voice volume volume %f", volume);
mWaitWorkCV.signal();
if (command->mWaitStatus) {
command->mCond.wait(mLock);
status = command->mStatus;
mWaitWorkCV.signal();
}
return status;
}
// insertCommand_l() must be called with mLock held // insertCommand_l() must be called with mLock held
void AudioPolicyService::AudioCommandThread::insertCommand_l(AudioCommand *command, int delayMs) void AudioPolicyService::AudioCommandThread::insertCommand_l(AudioCommand *command, int delayMs)
{ {

View File

@@ -105,6 +105,7 @@ public:
virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys); virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys);
virtual status_t startTone(ToneGenerator::tone_type tone, AudioSystem::stream_type stream); virtual status_t startTone(ToneGenerator::tone_type tone, AudioSystem::stream_type stream);
virtual status_t stopTone(); virtual status_t stopTone();
virtual status_t setVoiceVolume(float volume, int delayMs = 0);
private: private:
AudioPolicyService(); AudioPolicyService();
@@ -125,7 +126,8 @@ private:
START_TONE, START_TONE,
STOP_TONE, STOP_TONE,
SET_VOLUME, SET_VOLUME,
SET_PARAMETERS SET_PARAMETERS,
SET_VOICE_VOLUME
}; };
AudioCommandThread (); AudioCommandThread ();
@@ -140,6 +142,7 @@ private:
void stopToneCommand(); void stopToneCommand();
status_t volumeCommand(int stream, float volume, int output, int delayMs = 0); status_t volumeCommand(int stream, float volume, int output, int delayMs = 0);
status_t parametersCommand(int ioHandle, const String8& keyValuePairs, int delayMs = 0); status_t parametersCommand(int ioHandle, const String8& keyValuePairs, int delayMs = 0);
status_t voiceVolumeCommand(float volume, int delayMs = 0);
void insertCommand_l(AudioCommand *command, int delayMs = 0); void insertCommand_l(AudioCommand *command, int delayMs = 0);
private: private:
@@ -166,12 +169,17 @@ private:
float mVolume; float mVolume;
int mIO; int mIO;
}; };
class ParametersData { class ParametersData {
public: public:
int mIO; int mIO;
String8 mKeyValuePairs; String8 mKeyValuePairs;
}; };
class VoiceVolumeData {
public:
float mVolume;
};
Mutex mLock; Mutex mLock;
Condition mWaitWorkCV; Condition mWaitWorkCV;

View File

@@ -335,6 +335,13 @@ status_t AudioSystem::getInputBufferSize(uint32_t sampleRate, int format, int ch
return NO_ERROR; return NO_ERROR;
} }
status_t AudioSystem::setVoiceVolume(float value)
{
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
return af->setVoiceVolume(value);
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who) { void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who) {

View File

@@ -59,7 +59,8 @@ enum {
RESTORE_OUTPUT, RESTORE_OUTPUT,
OPEN_INPUT, OPEN_INPUT,
CLOSE_INPUT, CLOSE_INPUT,
SET_STREAM_OUTPUT SET_STREAM_OUTPUT,
SET_VOICE_VOLUME
}; };
class BpAudioFlinger : public BpInterface<IAudioFlinger> class BpAudioFlinger : public BpInterface<IAudioFlinger>
@@ -455,6 +456,15 @@ public:
remote()->transact(SET_STREAM_OUTPUT, data, &reply); remote()->transact(SET_STREAM_OUTPUT, data, &reply);
return reply.readInt32(); return reply.readInt32();
} }
virtual status_t setVoiceVolume(float volume)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
data.writeFloat(volume);
remote()->transact(SET_VOICE_VOLUME, data, &reply);
return reply.readInt32();
}
}; };
IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger"); IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger");
@@ -700,6 +710,12 @@ status_t BnAudioFlinger::onTransact(
reply->writeInt32(setStreamOutput(stream, output)); reply->writeInt32(setStreamOutput(stream, output));
return NO_ERROR; return NO_ERROR;
} break; } break;
case SET_VOICE_VOLUME: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
float volume = data.readFloat();
reply->writeInt32( setVoiceVolume(volume) );
return NO_ERROR;
} break;
default: default:
return BBinder::onTransact(code, data, reply, flags); return BBinder::onTransact(code, data, reply, flags);
} }