Implement StreamOut::setVolume
Bug: 157158109
Test: boot, check if audio works
Signed-off-by: Roman Kiryanov <rkir@google.com>
Change-Id: I8e40cc7effe590aefbc870b4103c97a648bd3f9a
Merged-In: I8e40cc7effe590aefbc870b4103c97a648bd3f9a
diff --git a/audio/stream_out.cpp b/audio/stream_out.cpp
index 8de1963..f6ae044 100644
--- a/audio/stream_out.cpp
+++ b/audio/stream_out.cpp
@@ -186,6 +186,7 @@
const size_t availToRead = mDataMQ.availableToRead();
size_t written = 0;
if (mDataMQ.read(&mBuffer[0], availToRead)) {
+ applyVolume(&mBuffer[0], availToRead, mStream->getVolumeNumerator());
status.retval = doWriteImpl(&mBuffer[0], availToRead, written);
mPos.addFrames(pcm_bytes_to_frames(mPcm.get(), written));
@@ -198,6 +199,21 @@
return status;
}
+ static void applyVolume(void *buf, const size_t szBytes, const int32_t numerator) {
+ constexpr int32_t kDenominator = StreamOut::kVolumeDenominator;
+
+ if (numerator == kDenominator) {
+ return;
+ }
+
+ int16_t *samples = static_cast<int16_t *>(buf);
+ std::for_each(samples,
+ samples + szBytes / sizeof(*samples),
+ [numerator](int16_t &x) {
+ x = (x * numerator + kDenominator / 2) / kDenominator;
+ });
+ }
+
IStreamOut::WriteStatus doGetPresentationPosition() {
IStreamOut::WriteStatus status;
@@ -413,9 +429,12 @@
}
Return<Result> StreamOut::setVolume(float left, float right) {
- (void)left;
- (void)right;
- return Result::NOT_SUPPORTED;
+ if (left < 0.0f || left > 1.0f || right < 0.0f || right > 1.0f) {
+ return Result::INVALID_ARGUMENTS;
+ }
+
+ mVolumeNumerator = int16_t((left + right) * kVolumeDenominator / 2);
+ return Result::OK;
}
Return<void> StreamOut::updateSourceMetadata(const SourceMetadata& sourceMetadata) {
diff --git a/audio/stream_out.h b/audio/stream_out.h
index c55ad8c..83987ad 100644
--- a/audio/stream_out.h
+++ b/audio/stream_out.h
@@ -15,6 +15,7 @@
*/
#pragma once
+#include <atomic>
#include <android/hardware/audio/6.0/IStreamOut.h>
#include <android/hardware/audio/6.0/IDevice.h>
#include "stream_common.h"
@@ -44,6 +45,8 @@
const SourceMetadata& sourceMetadata);
~StreamOut();
+ static constexpr int16_t kVolumeDenominator = 1 << 14;
+
// IStream
Return<uint64_t> getFrameSize() override;
Return<uint64_t> getFrameCount() override;
@@ -101,12 +104,15 @@
Return<void> getPlaybackRateParameters(getPlaybackRateParameters_cb _hidl_cb) override;
Return<Result> setPlaybackRateParameters(const PlaybackRate &playbackRate) override;
+ int16_t getVolumeNumerator() const { return mVolumeNumerator; };
+
private:
sp<IDevice> mDev;
void (* const mUnrefDevice)(IDevice*);
const StreamCommon mCommon;
const SourceMetadata mSourceMetadata;
std::unique_ptr<IOThread> mWriteThread;
+ std::atomic<int16_t> mVolumeNumerator = kVolumeDenominator;
};
} // namespace implementation