Loading audio/aidl/default/Android.bp +5 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ cc_defaults { "libbinder_ndk", "libcutils", "libfmq", "libnbaio_mono", "libstagefright_foundation", "libtinyalsav2", "libutils", Loading Loading @@ -76,6 +77,10 @@ cc_library { "Stream.cpp", "StreamStub.cpp", "Telephony.cpp", "r_submix/ModuleRemoteSubmix.cpp", "r_submix/RemoteSubmixUtils.cpp", "r_submix/SubmixRoute.cpp", "r_submix/StreamRemoteSubmix.cpp", "usb/ModuleUsb.cpp", "usb/StreamUsb.cpp", "usb/UsbAlsaMixerControl.cpp", Loading audio/aidl/default/Module.cpp +16 −3 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include "core-impl/Bluetooth.h" #include "core-impl/Module.h" #include "core-impl/ModuleRemoteSubmix.h" #include "core-impl/ModuleUsb.h" #include "core-impl/SoundDose.h" #include "core-impl/StreamStub.h" Loading Loading @@ -111,8 +112,9 @@ std::shared_ptr<Module> Module::createInstance(Type type) { switch (type) { case Module::Type::USB: return ndk::SharedRefBase::make<ModuleUsb>(type); case Type::DEFAULT: case Type::R_SUBMIX: return ndk::SharedRefBase::make<ModuleRemoteSubmix>(type); case Type::DEFAULT: default: return ndk::SharedRefBase::make<Module>(type); } Loading Loading @@ -181,8 +183,8 @@ ndk::ScopedAStatus Module::createStreamContext( StreamContext temp( std::make_unique<StreamContext::CommandMQ>(1, true /*configureEventFlagWord*/), std::make_unique<StreamContext::ReplyMQ>(1, true /*configureEventFlagWord*/), portConfigIt->format.value(), portConfigIt->channelMask.value(), portConfigIt->sampleRate.value().value, flags, portConfigIt->portId, portConfigIt->format.value(), portConfigIt->channelMask.value(), portConfigIt->sampleRate.value().value, flags, portConfigIt->ext.get<AudioPortExt::mix>().handle, std::make_unique<StreamContext::DataMQ>(frameSize * in_bufferSizeFrames), asyncCallback, outEventCallback, params); Loading Loading @@ -490,6 +492,17 @@ ndk::ScopedAStatus Module::connectExternalDevice(const AudioPort& in_templateIdA return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } for (auto profile : connectedPort.profiles) { if (profile.channelMasks.empty()) { LOG(ERROR) << __func__ << ": the profile " << profile.name << " has no channel masks"; return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } if (profile.sampleRates.empty()) { LOG(ERROR) << __func__ << ": the profile " << profile.name << " has no sample rates"; return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } } connectedPort.id = ++getConfig().nextPortId; auto [connectedPortsIt, _] = mConnectedDevicePorts.insert(std::pair(connectedPort.id, std::vector<int32_t>())); Loading audio/aidl/default/Stream.cpp +27 −12 Original line number Diff line number Diff line Loading @@ -166,10 +166,15 @@ StreamInWorkerLogic::Status StreamInWorkerLogic::cycle() { case Tag::start: if (mState == StreamDescriptor::State::STANDBY || mState == StreamDescriptor::State::DRAINING) { if (::android::status_t status = mDriver->start(); status == ::android::OK) { populateReply(&reply, mIsConnected); mState = mState == StreamDescriptor::State::STANDBY ? StreamDescriptor::State::IDLE : StreamDescriptor::State::ACTIVE; } else { LOG(ERROR) << __func__ << ": start failed: " << status; mState = StreamDescriptor::State::ERROR; } } else { populateReplyWrongState(&reply, command); } Loading Loading @@ -377,26 +382,36 @@ StreamOutWorkerLogic::Status StreamOutWorkerLogic::cycle() { populateReply(&reply, mIsConnected); break; case Tag::start: { bool commandAccepted = true; std::optional<StreamDescriptor::State> nextState; switch (mState) { case StreamDescriptor::State::STANDBY: mState = StreamDescriptor::State::IDLE; nextState = StreamDescriptor::State::IDLE; break; case StreamDescriptor::State::PAUSED: mState = StreamDescriptor::State::ACTIVE; nextState = StreamDescriptor::State::ACTIVE; break; case StreamDescriptor::State::DRAIN_PAUSED: switchToTransientState(StreamDescriptor::State::DRAINING); nextState = StreamDescriptor::State::DRAINING; break; case StreamDescriptor::State::TRANSFER_PAUSED: switchToTransientState(StreamDescriptor::State::TRANSFERRING); nextState = StreamDescriptor::State::TRANSFERRING; break; default: populateReplyWrongState(&reply, command); commandAccepted = false; } if (commandAccepted) { if (nextState.has_value()) { if (::android::status_t status = mDriver->start(); status == ::android::OK) { populateReply(&reply, mIsConnected); if (*nextState == StreamDescriptor::State::IDLE || *nextState == StreamDescriptor::State::ACTIVE) { mState = *nextState; } else { switchToTransientState(*nextState); } } else { LOG(ERROR) << __func__ << ": start failed: " << status; mState = StreamDescriptor::State::ERROR; } } } break; case Tag::burst: Loading audio/aidl/default/StreamStub.cpp +39 −8 Original line number Diff line number Diff line Loading @@ -33,33 +33,67 @@ namespace aidl::android::hardware::audio::core { StreamStub::StreamStub(const Metadata& metadata, StreamContext&& context) : StreamCommonImpl(metadata, std::move(context)), mFrameSizeBytes(context.getFrameSize()), mSampleRate(context.getSampleRate()), mIsAsynchronous(!!context.getAsyncCallback()), mFrameSizeBytes(getContext().getFrameSize()), mSampleRate(getContext().getSampleRate()), mIsAsynchronous(!!getContext().getAsyncCallback()), mIsInput(isInput(metadata)) {} ::android::status_t StreamStub::init() { mIsInitialized = true; usleep(500); return ::android::OK; } ::android::status_t StreamStub::drain(StreamDescriptor::DrainMode) { if (!mIsInitialized) { LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver"; } usleep(500); return ::android::OK; } ::android::status_t StreamStub::flush() { if (!mIsInitialized) { LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver"; } usleep(500); return ::android::OK; } ::android::status_t StreamStub::pause() { if (!mIsInitialized) { LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver"; } usleep(500); return ::android::OK; } ::android::status_t StreamStub::standby() { if (!mIsInitialized) { LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver"; } usleep(500); mIsStandby = true; return ::android::OK; } ::android::status_t StreamStub::start() { if (!mIsInitialized) { LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver"; } usleep(500); mIsStandby = false; return ::android::OK; } ::android::status_t StreamStub::transfer(void* buffer, size_t frameCount, size_t* actualFrameCount, int32_t* latencyMs) { if (!mIsInitialized) { LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver"; } if (mIsStandby) { LOG(FATAL) << __func__ << ": must not happen while in standby"; } static constexpr float kMicrosPerSecond = MICROS_PER_SECOND; static constexpr float kScaleFactor = .8f; if (mIsAsynchronous) { Loading @@ -80,13 +114,10 @@ StreamStub::StreamStub(const Metadata& metadata, StreamContext&& context) return ::android::OK; } ::android::status_t StreamStub::standby() { usleep(500); return ::android::OK; void StreamStub::shutdown() { mIsInitialized = false; } void StreamStub::shutdown() {} StreamInStub::StreamInStub(const SinkMetadata& sinkMetadata, StreamContext&& context, const std::vector<MicrophoneInfo>& microphones) : StreamStub(sinkMetadata, std::move(context)), StreamIn(microphones) {} Loading audio/aidl/default/include/core-impl/ModuleRemoteSubmix.h 0 → 100644 +59 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include "core-impl/Module.h" namespace aidl::android::hardware::audio::core { class ModuleRemoteSubmix : public Module { public: explicit ModuleRemoteSubmix(Module::Type type) : Module(type) {} private: // IModule interfaces ndk::ScopedAStatus getTelephony(std::shared_ptr<ITelephony>* _aidl_return) override; ndk::ScopedAStatus getBluetooth(std::shared_ptr<IBluetooth>* _aidl_return) override; ndk::ScopedAStatus getMicMute(bool* _aidl_return) override; ndk::ScopedAStatus setMicMute(bool in_mute) override; // Module interfaces ndk::ScopedAStatus createInputStream( const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata, StreamContext&& context, const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones, std::shared_ptr<StreamIn>* result) override; ndk::ScopedAStatus createOutputStream( const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata, StreamContext&& context, const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>& offloadInfo, std::shared_ptr<StreamOut>* result) override; ndk::ScopedAStatus populateConnectedDevicePort( ::aidl::android::media::audio::common::AudioPort* audioPort) override; ndk::ScopedAStatus checkAudioPatchEndpointsMatch( const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sources, const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sinks) override; void onExternalDeviceConnectionChanged( const ::aidl::android::media::audio::common::AudioPort& audioPort, bool connected) override; ndk::ScopedAStatus onMasterMuteChanged(bool mute) override; ndk::ScopedAStatus onMasterVolumeChanged(float volume) override; }; } // namespace aidl::android::hardware::audio::core Loading
audio/aidl/default/Android.bp +5 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ cc_defaults { "libbinder_ndk", "libcutils", "libfmq", "libnbaio_mono", "libstagefright_foundation", "libtinyalsav2", "libutils", Loading Loading @@ -76,6 +77,10 @@ cc_library { "Stream.cpp", "StreamStub.cpp", "Telephony.cpp", "r_submix/ModuleRemoteSubmix.cpp", "r_submix/RemoteSubmixUtils.cpp", "r_submix/SubmixRoute.cpp", "r_submix/StreamRemoteSubmix.cpp", "usb/ModuleUsb.cpp", "usb/StreamUsb.cpp", "usb/UsbAlsaMixerControl.cpp", Loading
audio/aidl/default/Module.cpp +16 −3 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include "core-impl/Bluetooth.h" #include "core-impl/Module.h" #include "core-impl/ModuleRemoteSubmix.h" #include "core-impl/ModuleUsb.h" #include "core-impl/SoundDose.h" #include "core-impl/StreamStub.h" Loading Loading @@ -111,8 +112,9 @@ std::shared_ptr<Module> Module::createInstance(Type type) { switch (type) { case Module::Type::USB: return ndk::SharedRefBase::make<ModuleUsb>(type); case Type::DEFAULT: case Type::R_SUBMIX: return ndk::SharedRefBase::make<ModuleRemoteSubmix>(type); case Type::DEFAULT: default: return ndk::SharedRefBase::make<Module>(type); } Loading Loading @@ -181,8 +183,8 @@ ndk::ScopedAStatus Module::createStreamContext( StreamContext temp( std::make_unique<StreamContext::CommandMQ>(1, true /*configureEventFlagWord*/), std::make_unique<StreamContext::ReplyMQ>(1, true /*configureEventFlagWord*/), portConfigIt->format.value(), portConfigIt->channelMask.value(), portConfigIt->sampleRate.value().value, flags, portConfigIt->portId, portConfigIt->format.value(), portConfigIt->channelMask.value(), portConfigIt->sampleRate.value().value, flags, portConfigIt->ext.get<AudioPortExt::mix>().handle, std::make_unique<StreamContext::DataMQ>(frameSize * in_bufferSizeFrames), asyncCallback, outEventCallback, params); Loading Loading @@ -490,6 +492,17 @@ ndk::ScopedAStatus Module::connectExternalDevice(const AudioPort& in_templateIdA return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } for (auto profile : connectedPort.profiles) { if (profile.channelMasks.empty()) { LOG(ERROR) << __func__ << ": the profile " << profile.name << " has no channel masks"; return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } if (profile.sampleRates.empty()) { LOG(ERROR) << __func__ << ": the profile " << profile.name << " has no sample rates"; return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } } connectedPort.id = ++getConfig().nextPortId; auto [connectedPortsIt, _] = mConnectedDevicePorts.insert(std::pair(connectedPort.id, std::vector<int32_t>())); Loading
audio/aidl/default/Stream.cpp +27 −12 Original line number Diff line number Diff line Loading @@ -166,10 +166,15 @@ StreamInWorkerLogic::Status StreamInWorkerLogic::cycle() { case Tag::start: if (mState == StreamDescriptor::State::STANDBY || mState == StreamDescriptor::State::DRAINING) { if (::android::status_t status = mDriver->start(); status == ::android::OK) { populateReply(&reply, mIsConnected); mState = mState == StreamDescriptor::State::STANDBY ? StreamDescriptor::State::IDLE : StreamDescriptor::State::ACTIVE; } else { LOG(ERROR) << __func__ << ": start failed: " << status; mState = StreamDescriptor::State::ERROR; } } else { populateReplyWrongState(&reply, command); } Loading Loading @@ -377,26 +382,36 @@ StreamOutWorkerLogic::Status StreamOutWorkerLogic::cycle() { populateReply(&reply, mIsConnected); break; case Tag::start: { bool commandAccepted = true; std::optional<StreamDescriptor::State> nextState; switch (mState) { case StreamDescriptor::State::STANDBY: mState = StreamDescriptor::State::IDLE; nextState = StreamDescriptor::State::IDLE; break; case StreamDescriptor::State::PAUSED: mState = StreamDescriptor::State::ACTIVE; nextState = StreamDescriptor::State::ACTIVE; break; case StreamDescriptor::State::DRAIN_PAUSED: switchToTransientState(StreamDescriptor::State::DRAINING); nextState = StreamDescriptor::State::DRAINING; break; case StreamDescriptor::State::TRANSFER_PAUSED: switchToTransientState(StreamDescriptor::State::TRANSFERRING); nextState = StreamDescriptor::State::TRANSFERRING; break; default: populateReplyWrongState(&reply, command); commandAccepted = false; } if (commandAccepted) { if (nextState.has_value()) { if (::android::status_t status = mDriver->start(); status == ::android::OK) { populateReply(&reply, mIsConnected); if (*nextState == StreamDescriptor::State::IDLE || *nextState == StreamDescriptor::State::ACTIVE) { mState = *nextState; } else { switchToTransientState(*nextState); } } else { LOG(ERROR) << __func__ << ": start failed: " << status; mState = StreamDescriptor::State::ERROR; } } } break; case Tag::burst: Loading
audio/aidl/default/StreamStub.cpp +39 −8 Original line number Diff line number Diff line Loading @@ -33,33 +33,67 @@ namespace aidl::android::hardware::audio::core { StreamStub::StreamStub(const Metadata& metadata, StreamContext&& context) : StreamCommonImpl(metadata, std::move(context)), mFrameSizeBytes(context.getFrameSize()), mSampleRate(context.getSampleRate()), mIsAsynchronous(!!context.getAsyncCallback()), mFrameSizeBytes(getContext().getFrameSize()), mSampleRate(getContext().getSampleRate()), mIsAsynchronous(!!getContext().getAsyncCallback()), mIsInput(isInput(metadata)) {} ::android::status_t StreamStub::init() { mIsInitialized = true; usleep(500); return ::android::OK; } ::android::status_t StreamStub::drain(StreamDescriptor::DrainMode) { if (!mIsInitialized) { LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver"; } usleep(500); return ::android::OK; } ::android::status_t StreamStub::flush() { if (!mIsInitialized) { LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver"; } usleep(500); return ::android::OK; } ::android::status_t StreamStub::pause() { if (!mIsInitialized) { LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver"; } usleep(500); return ::android::OK; } ::android::status_t StreamStub::standby() { if (!mIsInitialized) { LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver"; } usleep(500); mIsStandby = true; return ::android::OK; } ::android::status_t StreamStub::start() { if (!mIsInitialized) { LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver"; } usleep(500); mIsStandby = false; return ::android::OK; } ::android::status_t StreamStub::transfer(void* buffer, size_t frameCount, size_t* actualFrameCount, int32_t* latencyMs) { if (!mIsInitialized) { LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver"; } if (mIsStandby) { LOG(FATAL) << __func__ << ": must not happen while in standby"; } static constexpr float kMicrosPerSecond = MICROS_PER_SECOND; static constexpr float kScaleFactor = .8f; if (mIsAsynchronous) { Loading @@ -80,13 +114,10 @@ StreamStub::StreamStub(const Metadata& metadata, StreamContext&& context) return ::android::OK; } ::android::status_t StreamStub::standby() { usleep(500); return ::android::OK; void StreamStub::shutdown() { mIsInitialized = false; } void StreamStub::shutdown() {} StreamInStub::StreamInStub(const SinkMetadata& sinkMetadata, StreamContext&& context, const std::vector<MicrophoneInfo>& microphones) : StreamStub(sinkMetadata, std::move(context)), StreamIn(microphones) {} Loading
audio/aidl/default/include/core-impl/ModuleRemoteSubmix.h 0 → 100644 +59 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include "core-impl/Module.h" namespace aidl::android::hardware::audio::core { class ModuleRemoteSubmix : public Module { public: explicit ModuleRemoteSubmix(Module::Type type) : Module(type) {} private: // IModule interfaces ndk::ScopedAStatus getTelephony(std::shared_ptr<ITelephony>* _aidl_return) override; ndk::ScopedAStatus getBluetooth(std::shared_ptr<IBluetooth>* _aidl_return) override; ndk::ScopedAStatus getMicMute(bool* _aidl_return) override; ndk::ScopedAStatus setMicMute(bool in_mute) override; // Module interfaces ndk::ScopedAStatus createInputStream( const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata, StreamContext&& context, const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones, std::shared_ptr<StreamIn>* result) override; ndk::ScopedAStatus createOutputStream( const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata, StreamContext&& context, const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>& offloadInfo, std::shared_ptr<StreamOut>* result) override; ndk::ScopedAStatus populateConnectedDevicePort( ::aidl::android::media::audio::common::AudioPort* audioPort) override; ndk::ScopedAStatus checkAudioPatchEndpointsMatch( const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sources, const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sinks) override; void onExternalDeviceConnectionChanged( const ::aidl::android::media::audio::common::AudioPort& audioPort, bool connected) override; ndk::ScopedAStatus onMasterMuteChanged(bool mute) override; ndk::ScopedAStatus onMasterVolumeChanged(float volume) override; }; } // namespace aidl::android::hardware::audio::core