1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <iostream> 20 #include <map> 21 #include <memory> 22 #include <mutex> 23 #include <string> 24 #include <vector> 25 26 #include <android-base/thread_annotations.h> 27 #include <android/binder_auto_utils.h> 28 29 extern "C" { 30 #include <tinyalsa/mixer.h> 31 } 32 33 namespace aidl::android::hardware::audio::core::alsa { 34 35 class Mixer { 36 public: 37 explicit Mixer(int card); 38 ~Mixer(); 39 isValid()40 bool isValid() const { return mMixer != nullptr; } 41 42 ndk::ScopedAStatus setMasterMute(bool muted); 43 ndk::ScopedAStatus setMasterVolume(float volume); 44 ndk::ScopedAStatus setMicGain(float gain); 45 ndk::ScopedAStatus setMicMute(bool muted); 46 ndk::ScopedAStatus setVolumes(const std::vector<float>& volumes); 47 48 private: 49 enum Control { 50 MASTER_SWITCH, 51 MASTER_VOLUME, 52 HW_VOLUME, 53 MIC_SWITCH, 54 MIC_GAIN, 55 }; 56 using ControlNamesAndExpectedCtlType = std::pair<std::string, enum mixer_ctl_type>; 57 using Controls = std::map<Control, struct mixer_ctl*>; 58 59 friend std::ostream& operator<<(std::ostream&, Control); 60 static const std::map<Control, std::vector<ControlNamesAndExpectedCtlType>> kPossibleControls; 61 static Controls initializeMixerControls(struct mixer* mixer); 62 63 ndk::ScopedAStatus setMixerControlMute(Control ctl, bool muted); 64 ndk::ScopedAStatus setMixerControlVolume(Control ctl, float volume); 65 66 int setMixerControlPercent(struct mixer_ctl* ctl, int percent) REQUIRES(mMixerAccess); 67 int setMixerControlPercent(struct mixer_ctl* ctl, const std::vector<int>& percents) 68 REQUIRES(mMixerAccess); 69 int setMixerControlValue(struct mixer_ctl* ctl, int value) REQUIRES(mMixerAccess); 70 71 // Since ALSA functions do not use internal locking, enforce thread safety at our level. 72 std::mutex mMixerAccess; 73 // The mixer object is owned by ALSA and will be released when the mixer is closed. 74 struct mixer* const mMixer; 75 // `mMixerControls` will only be initialized in constructor. After that, it will only be 76 // read but not be modified. Each mixer_ctl object is owned by ALSA, it's life span is 77 // the same as of the mixer itself. 78 const Controls mMixerControls; 79 }; 80 81 } // namespace aidl::android::hardware::audio::core::alsa 82