blob: b39ee5ca3b48b1e16a1782776780c36a5eb04d46 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_MEDIA_AUDIO_AUDIO_CORE_DEVICE_CONFIG_H_
#define SRC_MEDIA_AUDIO_AUDIO_CORE_DEVICE_CONFIG_H_
#include <fuchsia/media/cpp/fidl.h>
#include <zircon/device/audio.h>
#include <unordered_set>
#include <vector>
#include "src/media/audio/audio_core/loudness_transform.h"
#include "src/media/audio/audio_core/pipeline_config.h"
namespace media::audio {
class DeviceConfig {
public:
using UsageSupportSet = std::unordered_set<uint32_t>;
// A routing profile for a device.
class OutputDeviceProfile {
public:
OutputDeviceProfile() = default;
OutputDeviceProfile(bool eligible_for_loopback, UsageSupportSet output_usage_support_set,
bool independent_volume_control = false,
PipelineConfig pipeline_config = PipelineConfig::Default())
: eligible_for_loopback_(eligible_for_loopback),
independent_volume_control_(independent_volume_control),
pipeline_config_(std::move(pipeline_config)),
output_usage_support_set_(std::move(output_usage_support_set)) {}
bool supports_usage(fuchsia::media::AudioRenderUsage usage) const {
return !output_usage_support_set_ ||
output_usage_support_set_->find(fidl::ToUnderlying(usage)) !=
output_usage_support_set_->end();
}
// Whether this device is eligible to be looped back to loopback capturers.
bool eligible_for_loopback() const { return eligible_for_loopback_; }
const std::shared_ptr<LoudnessTransform>& loudness_transform() const;
// Whether this device has independent volume control, and should therefore
// receive routed streams at unity gain.
bool independent_volume_control() const { return independent_volume_control_; }
const PipelineConfig& pipeline_config() const { return pipeline_config_; }
private:
const static std::shared_ptr<LoudnessTransform> kNoOpTransform;
bool eligible_for_loopback_ = true;
bool independent_volume_control_ = false;
PipelineConfig pipeline_config_ = PipelineConfig::Default();
// The set of output usages supported by the device.
std::optional<UsageSupportSet> output_usage_support_set_;
};
DeviceConfig() {}
DeviceConfig(
std::vector<std::pair<audio_stream_unique_id_t, OutputDeviceProfile>> output_device_profiles,
std::optional<OutputDeviceProfile> default_output_device_profile)
: output_device_profiles_(std::move(output_device_profiles)),
default_output_device_profile_(
default_output_device_profile.value_or(OutputDeviceProfile())) {}
const OutputDeviceProfile& output_device_profile(const audio_stream_unique_id_t& id) const {
auto it = std::find_if(
output_device_profiles_.begin(), output_device_profiles_.end(),
[id](auto set) { return std::memcmp(id.data, set.first.data, sizeof(id.data)) == 0; });
return it != output_device_profiles_.end() ? it->second : default_output_device_profile_;
}
const OutputDeviceProfile& default_output_device_profile() const {
return default_output_device_profile_;
}
// Searches device profiles for an effect with the specified instance name. Returns a pointer
// to the effect or nullptr if not found.
const PipelineConfig::Effect* FindEffect(const std::string& instance_name) const;
private:
friend class ProcessConfigBuilder;
// Profiles for explicitly configured devices.
std::vector<std::pair<audio_stream_unique_id_t, OutputDeviceProfile>> output_device_profiles_;
// The device profile to apply to devices without an explicit profile.
OutputDeviceProfile default_output_device_profile_;
};
} // namespace media::audio
#endif // SRC_MEDIA_AUDIO_AUDIO_CORE_DEVICE_CONFIG_H_