aaudio: implement IPlayer for MMAP playback streams
Make AudioStreamInternal derive from PlayerBase to
provide playback and volume control via IPlayer interface.
Bug: 62027849
Test: verify aaudio playback in MMAP mode and registration of aaudio
players in AudioService when active
Change-Id: Ia0878d46637c0a954d8a6259868a2d3bccf19119
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index 3a827f0..768d9db 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -62,6 +62,7 @@
, mAudioEndpoint()
, mServiceStreamHandle(AAUDIO_HANDLE_INVALID)
, mFramesPerBurst(16)
+ , mStreamVolume(1.0f)
, mServiceInterface(serviceInterface)
, mInService(inService) {
}
@@ -175,6 +176,10 @@
}
setState(AAUDIO_STREAM_STATE_OPEN);
+ // only connect to AudioManager if this is a playback stream running in client process
+ if (!mInService && getDirection() == AAUDIO_DIRECTION_OUTPUT) {
+ init(android::PLAYER_TYPE_AAUDIO, AUDIO_USAGE_MEDIA);
+ }
}
return result;
}
@@ -231,7 +236,7 @@
startTime = AudioClock::getNanoseconds();
mClockModel.start(startTime);
setState(AAUDIO_STREAM_STATE_STARTING);
- aaudio_result_t result = mServiceInterface.startStream(mServiceStreamHandle);;
+ aaudio_result_t result = AAudioConvert_androidToAAudioResult(startWithStatus());
if (result == AAUDIO_OK && getDataCallbackProc() != nullptr) {
// Launch the callback loop thread.
@@ -281,7 +286,7 @@
mClockModel.stop(AudioClock::getNanoseconds());
setState(AAUDIO_STREAM_STATE_PAUSING);
- return mServiceInterface.pauseStream(mServiceStreamHandle);
+ return AAudioConvert_androidToAAudioResult(pauseWithStatus());
}
aaudio_result_t AudioStreamInternal::requestPause()
@@ -330,7 +335,7 @@
mClockModel.stop(AudioClock::getNanoseconds());
setState(AAUDIO_STREAM_STATE_STOPPING);
- return mServiceInterface.stopStream(mServiceStreamHandle);
+ return AAudioConvert_androidToAAudioResult(stopWithStatus());
}
aaudio_result_t AudioStreamInternal::requestStop()
@@ -446,7 +451,8 @@
ALOGW("WARNING - processCommands() AAUDIO_SERVICE_EVENT_DISCONNECTED");
break;
case AAUDIO_SERVICE_EVENT_VOLUME:
- mVolumeRamp.setTarget((float) message->event.dataDouble);
+ mStreamVolume = (float)message->event.dataDouble;
+ doSetVolume();
ALOGD("processCommands() AAUDIO_SERVICE_EVENT_VOLUME %lf",
message->event.dataDouble);
break;
@@ -588,3 +594,32 @@
aaudio_result_t AudioStreamInternal::joinThread(void** returnArg) {
return AudioStream::joinThread(returnArg, calculateReasonableTimeout(getFramesPerBurst()));
}
+
+void AudioStreamInternal::doSetVolume() {
+ // No pan and only left volume is taken into account from IPLayer interface
+ mVolumeRamp.setTarget(mStreamVolume * mVolumeMultiplierL /* * mPanMultiplierL */);
+}
+
+
+//------------------------------------------------------------------------------
+// Implementation of PlayerBase
+status_t AudioStreamInternal::playerStart() {
+ return AAudioConvert_aaudioToAndroidStatus(mServiceInterface.startStream(mServiceStreamHandle));
+}
+
+status_t AudioStreamInternal::playerPause() {
+ return AAudioConvert_aaudioToAndroidStatus(mServiceInterface.pauseStream(mServiceStreamHandle));
+}
+
+status_t AudioStreamInternal::playerStop() {
+ return AAudioConvert_aaudioToAndroidStatus(mServiceInterface.stopStream(mServiceStreamHandle));
+}
+
+status_t AudioStreamInternal::playerSetVolume() {
+ doSetVolume();
+ return NO_ERROR;
+}
+
+void AudioStreamInternal::destroy() {
+ baseDestroy();
+}
diff --git a/media/libaaudio/src/client/AudioStreamInternal.h b/media/libaaudio/src/client/AudioStreamInternal.h
index a11f309..47aedad 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.h
+++ b/media/libaaudio/src/client/AudioStreamInternal.h
@@ -18,6 +18,7 @@
#define ANDROID_AAUDIO_AUDIO_STREAM_INTERNAL_H
#include <stdint.h>
+#include <media/PlayerBase.h>
#include <aaudio/AAudio.h>
#include "binding/IAAudioService.h"
@@ -34,7 +35,7 @@
namespace aaudio {
// A stream that talks to the AAudioService or directly to a HAL.
-class AudioStreamInternal : public AudioStream {
+class AudioStreamInternal : public AudioStream, public android::PlayerBase {
public:
AudioStreamInternal(AAudioServiceInterface &serviceInterface, bool inService);
@@ -89,6 +90,9 @@
// Calculate timeout based on framesPerBurst
int64_t calculateReasonableTimeout();
+ //PlayerBase virtuals
+ virtual void destroy();
+
protected:
aaudio_result_t processData(void *buffer,
@@ -124,6 +128,14 @@
// Calculate timeout for an operation involving framesPerOperation.
int64_t calculateReasonableTimeout(int32_t framesPerOperation);
+ void doSetVolume();
+
+ //PlayerBase virtuals
+ virtual status_t playerStart();
+ virtual status_t playerPause();
+ virtual status_t playerStop();
+ virtual status_t playerSetVolume();
+
aaudio_format_t mDeviceFormat = AAUDIO_FORMAT_UNSPECIFIED;
IsochronousClockModel mClockModel; // timing model for chasing the HAL
@@ -135,6 +147,7 @@
int32_t mXRunCount = 0; // how many underrun events?
LinearRamp mVolumeRamp;
+ float mStreamVolume;
// Offset from underlying frame position.
int64_t mFramesOffsetFromService = 0; // offset for timestamps