VolumeShaper: Initial implementation
The VolumeShaper is used to apply a volume
envelope to an AudioTrack or a MediaPlayer.
Test: CTS
Bug: 30920125
Bug: 31015569
Change-Id: I42e2f13bd6879299dc780e60d143c2d465483a44
diff --git a/media/libaudioclient/IAudioTrack.cpp b/media/libaudioclient/IAudioTrack.cpp
index 89e0fcc..79e864d 100644
--- a/media/libaudioclient/IAudioTrack.cpp
+++ b/media/libaudioclient/IAudioTrack.cpp
@@ -39,6 +39,8 @@
SET_PARAMETERS,
GET_TIMESTAMP,
SIGNAL,
+ APPLY_VOLUME_SHAPER,
+ GET_VOLUME_SHAPER_STATE,
};
class BpAudioTrack : public BpInterface<IAudioTrack>
@@ -143,6 +145,52 @@
data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
remote()->transact(SIGNAL, data, &reply);
}
+
+ virtual VolumeShaper::Status applyVolumeShaper(
+ const sp<VolumeShaper::Configuration>& configuration,
+ const sp<VolumeShaper::Operation>& operation) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
+
+ status_t status = configuration.get() == nullptr
+ ? data.writeInt32(0)
+ : data.writeInt32(1)
+ ?: configuration->writeToParcel(&data);
+ if (status != NO_ERROR) {
+ return VolumeShaper::Status(status);
+ }
+
+ status = operation.get() == nullptr
+ ? status = data.writeInt32(0)
+ : data.writeInt32(1)
+ ?: operation->writeToParcel(&data);
+ if (status != NO_ERROR) {
+ return VolumeShaper::Status(status);
+ }
+
+ int32_t remoteVolumeShaperStatus;
+ status = remote()->transact(APPLY_VOLUME_SHAPER, data, &reply)
+ ?: reply.readInt32(&remoteVolumeShaperStatus);
+
+ return VolumeShaper::Status(status ?: remoteVolumeShaperStatus);
+ }
+
+ virtual sp<VolumeShaper::State> getVolumeShaperState(int id) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
+
+ data.writeInt32(id);
+ status_t status = remote()->transact(GET_VOLUME_SHAPER_STATE, data, &reply);
+ if (status != NO_ERROR) {
+ return nullptr;
+ }
+ sp<VolumeShaper::State> state = new VolumeShaper::State;
+ status = state->readFromParcel(reply);
+ if (status != NO_ERROR) {
+ return nullptr;
+ }
+ return state;
+ }
};
IMPLEMENT_META_INTERFACE(AudioTrack, "android.media.IAudioTrack");
@@ -206,6 +254,40 @@
signal();
return NO_ERROR;
} break;
+ case APPLY_VOLUME_SHAPER: {
+ CHECK_INTERFACE(IAudioTrack, data, reply);
+ sp<VolumeShaper::Configuration> configuration;
+ sp<VolumeShaper::Operation> operation;
+
+ int32_t present;
+ status_t status = data.readInt32(&present);
+ if (status == NO_ERROR && present != 0) {
+ configuration = new VolumeShaper::Configuration();
+ status = configuration->readFromParcel(data);
+ }
+ status = status ?: data.readInt32(&present);
+ if (status == NO_ERROR && present != 0) {
+ operation = new VolumeShaper::Operation();
+ status = operation->readFromParcel(data);
+ }
+ if (status == NO_ERROR) {
+ status = (status_t)applyVolumeShaper(configuration, operation);
+ }
+ reply->writeInt32(status);
+ return NO_ERROR;
+ } break;
+ case GET_VOLUME_SHAPER_STATE: {
+ CHECK_INTERFACE(IAudioTrack, data, reply);
+ int id;
+ status_t status = data.readInt32(&id);
+ if (status == NO_ERROR) {
+ sp<VolumeShaper::State> state = getVolumeShaperState(id);
+ if (state.get() != nullptr) {
+ status = state->writeToParcel(reply);
+ }
+ }
+ return NO_ERROR;
+ } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}