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 <functional> 20 #include <iostream> 21 #include <memory> 22 #include <optional> 23 #include <vector> 24 25 #include <aidl/android/media/audio/common/AudioChannelLayout.h> 26 #include <aidl/android/media/audio/common/AudioFormatDescription.h> 27 #include <aidl/android/media/audio/common/AudioPort.h> 28 29 #include "core-impl/Stream.h" 30 31 extern "C" { 32 #include <tinyalsa/pcm.h> 33 #include "alsa_device_profile.h" 34 #include "alsa_device_proxy.h" 35 } 36 37 namespace aidl::android::hardware::audio::core::alsa { 38 39 struct DeviceProfile { 40 int card; 41 int device; 42 int direction; /* PCM_OUT or PCM_IN */ 43 bool isExternal; 44 }; 45 std::ostream& operator<<(std::ostream& os, const DeviceProfile& device); 46 47 class DeviceProxy { 48 public: 49 DeviceProxy(); // Constructs a "null" proxy. 50 explicit DeviceProxy(const DeviceProfile& deviceProfile); getProfile()51 alsa_device_profile* getProfile() { return mProfile.get(); } get()52 alsa_device_proxy* get() { return mProxy.get(); } 53 54 private: 55 static void alsaProxyDeleter(alsa_device_proxy* proxy); 56 using AlsaProxy = std::unique_ptr<alsa_device_proxy, decltype(alsaProxyDeleter)*>; 57 58 std::unique_ptr<alsa_device_profile> mProfile; 59 AlsaProxy mProxy; 60 }; 61 62 ::aidl::android::media::audio::common::AudioChannelLayout getChannelLayoutMaskFromChannelCount( 63 unsigned int channelCount, int isInput); 64 ::aidl::android::media::audio::common::AudioChannelLayout getChannelIndexMaskFromChannelCount( 65 unsigned int channelCount); 66 unsigned int getChannelCountFromChannelMask( 67 const ::aidl::android::media::audio::common::AudioChannelLayout& channelMask, bool isInput); 68 std::vector<::aidl::android::media::audio::common::AudioChannelLayout> getChannelMasksFromProfile( 69 const alsa_device_profile* profile); 70 std::optional<DeviceProfile> getDeviceProfile( 71 const ::aidl::android::media::audio::common::AudioDevice& audioDevice, bool isInput); 72 std::optional<DeviceProfile> getDeviceProfile( 73 const ::aidl::android::media::audio::common::AudioPort& audioPort); 74 std::optional<struct pcm_config> getPcmConfig(const StreamContext& context, bool isInput); 75 std::vector<int> getSampleRatesFromProfile(const alsa_device_profile* profile); 76 DeviceProxy openProxyForAttachedDevice(const DeviceProfile& deviceProfile, 77 struct pcm_config* pcmConfig, size_t bufferFrameCount); 78 DeviceProxy openProxyForExternalDevice(const DeviceProfile& deviceProfile, 79 struct pcm_config* pcmConfig, bool requireExactMatch); 80 DeviceProxy readAlsaDeviceInfo(const DeviceProfile& deviceProfile); 81 void resetTransferredFrames(DeviceProxy& proxy, uint64_t frames); 82 83 ::aidl::android::media::audio::common::AudioFormatDescription 84 c2aidl_pcm_format_AudioFormatDescription(enum pcm_format legacy); 85 pcm_format aidl2c_AudioFormatDescription_pcm_format( 86 const ::aidl::android::media::audio::common::AudioFormatDescription& aidl); 87 88 } // namespace aidl::android::hardware::audio::core::alsa 89