blob: 2504a97daeb5d73bfc6e0e6a91ac38ef98e384ca [file] [log] [blame]
// Copyright 2022 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.
#include "src/media/audio/services/device_registry/logging.h"
#include <fidl/fuchsia.audio.device/cpp/natural_types.h>
#include <fidl/fuchsia.hardware.audio.signalprocessing/cpp/fidl.h>
#include <fidl/fuchsia.hardware.audio/cpp/fidl.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/zx/time.h>
#include <iomanip>
#include <string>
#include "src/media/audio/services/device_registry/basic_types.h"
#include "src/media/audio/services/device_registry/control_creator_server.h"
#include "src/media/audio/services/device_registry/control_server.h"
#include "src/media/audio/services/device_registry/device.h"
#include "src/media/audio/services/device_registry/observer_server.h"
#include "src/media/audio/services/device_registry/provider_server.h"
#include "src/media/audio/services/device_registry/registry_server.h"
#include "src/media/audio/services/device_registry/ring_buffer_server.h"
namespace media_audio {
std::string UidToString(std::optional<UniqueId> unique_instance_id) {
if (!unique_instance_id) {
return "<none>";
}
auto id = *unique_instance_id;
char s[35];
sprintf(s,
"0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", //
id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7], //
id[8], id[9], id[10], id[11], id[12], id[13], id[14], id[15]);
s[34] = '\0';
std::string str(s);
if (id[0] == 0x55 && id[1] == 0x53 && id[2] == 0x42) { // ASCII 'U', 'S', 'B'
str += " (in the range reserved for USB devices)"; //
} else if (id[0] == 0x42 && id[1] == 0x54) { // ASCII 'B', 'T'
str += " (in the range reserved for Bluetooth devices)";
}
return str;
}
void LogStreamProperties(const fuchsia_hardware_audio::StreamProperties& stream_props) {
if constexpr (!kLogStreamConfigFidlResponseValues) {
return;
}
FX_LOGS(INFO) << "fuchsia_hardware_audio/StreamProperties";
FX_LOGS(INFO) << " unique_id " << UidToString(stream_props.unique_id());
FX_LOGS(INFO) << " is_input "
<< (stream_props.is_input() ? (*stream_props.is_input() ? "TRUE" : "FALSE")
: "<none> (non-compliant)");
FX_LOGS(INFO) << " can_mute "
<< (stream_props.can_mute() ? (*stream_props.can_mute() ? "TRUE" : "FALSE")
: "<none> (cannot mute)");
FX_LOGS(INFO) << " can_agc "
<< (stream_props.can_agc() ? (*stream_props.can_agc() ? "TRUE" : "FALSE")
: "<none> (cannot enable AGC)");
if (stream_props.min_gain_db()) {
FX_LOGS(INFO) << " min_gain_db " << *stream_props.min_gain_db() << " dB";
} else {
FX_LOGS(INFO) << " min_gain_db <none> (non-compliant)";
}
if (stream_props.max_gain_db()) {
FX_LOGS(INFO) << " max_gain_db " << *stream_props.max_gain_db() << " dB";
} else {
FX_LOGS(INFO) << " max_gain_db <none> (non-compliant)";
}
if (stream_props.gain_step_db()) {
FX_LOGS(INFO) << " gain_step_db " << *stream_props.gain_step_db() << " dB";
} else {
FX_LOGS(INFO) << " gain_step_db <none> (non-compliant)";
}
if (stream_props.plug_detect_capabilities()) {
FX_LOGS(INFO) << " plug_detect_caps " << *stream_props.plug_detect_capabilities();
} else {
FX_LOGS(INFO) << " plug_detect_caps <none> (non-compliant)";
}
FX_LOGS(INFO) << " manufacturer "
<< (stream_props.manufacturer()
? ("'" +
std::string(stream_props.manufacturer()->data(),
stream_props.manufacturer()->size()) +
"'")
: "<none>");
FX_LOGS(INFO) << " product "
<< (stream_props.product() ? ("'" +
std::string(stream_props.product()->data(),
stream_props.product()->size()) +
"'")
: "<none>");
std::string clock_domain_str{" clock _domain "};
if (stream_props.clock_domain()) {
clock_domain_str += std::to_string(*stream_props.clock_domain());
if (*stream_props.clock_domain() == fuchsia_hardware_audio::kClockDomainMonotonic) {
clock_domain_str += " (CLOCK_DOMAIN_MONOTONIC)";
} else if (*stream_props.clock_domain() == fuchsia_hardware_audio::kClockDomainExternal) {
clock_domain_str += " (CLOCK_DOMAIN_EXTERNAL)";
}
} else {
clock_domain_str += "<none> (non-compliant)";
}
FX_LOGS(INFO) << clock_domain_str;
}
void LogElementRingBufferFormatSets(
const std::vector<fuchsia_audio_device::ElementRingBufferFormatSet>&
element_ring_buffer_format_sets) {
if constexpr (!kLogStreamConfigFidlResponseValues && !kLogCompositeFidlResponseValues) {
return;
}
for (const auto& element_ring_buffer_format_set : element_ring_buffer_format_sets) {
LogElementRingBufferFormatSet(element_ring_buffer_format_set);
}
}
void LogElementRingBufferFormatSet(
const fuchsia_audio_device::ElementRingBufferFormatSet& element_ring_buffer_format_set) {
if constexpr (!kLogStreamConfigFidlResponseValues && !kLogCompositeFidlResponseValues) {
return;
}
if (element_ring_buffer_format_set.element_id()) {
FX_LOGS(INFO) << " .element_id " << *element_ring_buffer_format_set.element_id();
} else {
FX_LOGS(INFO) << " .element_id <none> (non-compliant)";
}
if (element_ring_buffer_format_set.format_sets()) {
FX_LOGS(INFO) << " .format_set [" << element_ring_buffer_format_set.format_sets()->size()
<< "]";
LogTranslatedRingBufferFormatSets(*element_ring_buffer_format_set.format_sets());
} else {
FX_LOGS(INFO) << " .format_set <none> (non-compliant)";
}
}
void LogTranslatedRingBufferFormatSets(
const std::vector<fuchsia_audio_device::PcmFormatSet>& translated_ring_buffer_format_sets) {
if constexpr (!kLogStreamConfigFidlResponseValues && !kLogCompositeFidlResponseValues) {
return;
}
FX_LOGS(INFO) << "fuchsia_audio_device::translated_ring_buffer_format_sets";
FX_LOGS(INFO) << " PcmFormatSet[" << translated_ring_buffer_format_sets.size() << "]";
for (auto idx = 0u; idx < translated_ring_buffer_format_sets.size(); ++idx) {
FX_LOGS(INFO) << " [" << idx << "]";
LogTranslatedRingBufferFormatSet(translated_ring_buffer_format_sets[idx]);
}
}
void LogTranslatedRingBufferFormatSet(
const fuchsia_audio_device::PcmFormatSet& translated_ring_buffer_format_set) {
if constexpr (!kLogStreamConfigFidlResponseValues && !kLogCompositeFidlResponseValues) {
return;
}
if (translated_ring_buffer_format_set.channel_sets()) {
const auto& channel_sets = *translated_ring_buffer_format_set.channel_sets();
FX_LOGS(INFO) << " channel_sets [" << channel_sets.size() << "]";
for (auto idx = 0u; idx < channel_sets.size(); ++idx) {
if (!channel_sets[idx].attributes()) {
FX_LOGS(INFO) << " [" << idx << "] <none> (non-compliant)";
continue;
}
const auto& attribs = *channel_sets[idx].attributes();
FX_LOGS(INFO) << " [" << idx << "] attributes[" << attribs.size() << "]";
for (auto idx = 0u; idx < attribs.size(); ++idx) {
FX_LOGS(INFO) << " [" << idx << "]";
FX_LOGS(INFO) << " min_frequency "
<< (attribs[idx].min_frequency()
? std::to_string(*attribs[idx].min_frequency())
: "<none>");
FX_LOGS(INFO) << " max_frequency "
<< (attribs[idx].max_frequency()
? std::to_string(*attribs[idx].max_frequency())
: "<none>");
}
}
} else {
FX_LOGS(INFO) << " channel_sets <none> (non-compliant)";
}
if (translated_ring_buffer_format_set.sample_types()) {
const auto& sample_types = *translated_ring_buffer_format_set.sample_types();
FX_LOGS(INFO) << " sample_types [" << sample_types.size() << "]";
for (auto idx = 0u; idx < sample_types.size(); ++idx) {
FX_LOGS(INFO) << " [" << idx << "] " << sample_types[idx];
}
} else {
FX_LOGS(INFO) << " sample_types <none> (non-compliant)";
}
if (translated_ring_buffer_format_set.frame_rates()) {
const auto& frame_rates = *translated_ring_buffer_format_set.frame_rates();
FX_LOGS(INFO) << " frame_rates [" << frame_rates.size() << "]";
for (auto idx = 0u; idx < frame_rates.size(); ++idx) {
FX_LOGS(INFO) << " [" << idx << "] " << frame_rates[idx];
}
} else {
FX_LOGS(INFO) << " frame_rates <none> (non-compliant)";
}
}
void LogRingBufferFormatSets(
const std::vector<fuchsia_hardware_audio::SupportedFormats>& ring_buffer_format_sets) {
if constexpr (!kLogStreamConfigFidlResponseValues) {
return;
}
FX_LOGS(INFO) << "fuchsia_hardware_audio/SupportedFormats";
FX_LOGS(INFO) << " ring_buffer_format_sets [" << ring_buffer_format_sets.size() << "]";
for (auto idx = 0u; idx < ring_buffer_format_sets.size(); ++idx) {
auto ring_buffer_format_set = ring_buffer_format_sets[idx];
if (!ring_buffer_format_set.pcm_supported_formats()) {
FX_LOGS(INFO) << " [" << idx << "] <none> (non-compliant)";
continue;
}
FX_LOGS(INFO) << " [" << idx << "] pcm_supported_formats";
const auto& pcm_format_set = *ring_buffer_format_set.pcm_supported_formats();
if (pcm_format_set.channel_sets()) {
const auto& channel_sets = *pcm_format_set.channel_sets();
FX_LOGS(INFO) << " channel_sets [" << channel_sets.size() << "]";
for (auto idx = 0u; idx < channel_sets.size(); ++idx) {
if (!channel_sets[idx].attributes()) {
FX_LOGS(INFO) << " [" << idx << "] <none> (non-compliant)";
continue;
}
const auto& attribs = *channel_sets[idx].attributes();
FX_LOGS(INFO) << " [" << idx << "] attributes [" << attribs.size() << "]";
for (auto idx = 0u; idx < attribs.size(); ++idx) {
FX_LOGS(INFO) << " [" << idx << "]";
FX_LOGS(INFO) << " min_frequency "
<< (attribs[idx].min_frequency()
? std::to_string(*attribs[idx].min_frequency())
: "<none>");
FX_LOGS(INFO) << " max_frequency "
<< (attribs[idx].max_frequency()
? std::to_string(*attribs[idx].max_frequency())
: "<none>");
}
}
} else {
FX_LOGS(INFO) << " <none> (non-compliant)";
}
if (pcm_format_set.sample_formats()) {
const auto& sample_formats = *pcm_format_set.sample_formats();
FX_LOGS(INFO) << " sample_formats [" << sample_formats.size() << "]";
for (auto idx = 0u; idx < sample_formats.size(); ++idx) {
FX_LOGS(INFO) << " [" << idx << "] " << sample_formats[idx];
}
} else {
FX_LOGS(INFO) << " <none> (non-compliant)";
}
if (pcm_format_set.bytes_per_sample()) {
const auto& bytes_per_sample = *pcm_format_set.bytes_per_sample();
FX_LOGS(INFO) << " bytes_per_sample [" << bytes_per_sample.size() << "]";
for (auto idx = 0u; idx < bytes_per_sample.size(); ++idx) {
FX_LOGS(INFO) << " [" << idx << "] "
<< static_cast<int16_t>(bytes_per_sample[idx]);
}
} else {
FX_LOGS(INFO) << " <none> (non-compliant)";
}
if (pcm_format_set.valid_bits_per_sample()) {
const auto& valid_bits_per_sample = *pcm_format_set.valid_bits_per_sample();
FX_LOGS(INFO) << " valid_bits_per_sample [" << valid_bits_per_sample.size() << "]";
for (auto idx = 0u; idx < valid_bits_per_sample.size(); ++idx) {
FX_LOGS(INFO) << " [" << idx << "] "
<< static_cast<int16_t>(valid_bits_per_sample[idx]);
}
} else {
FX_LOGS(INFO) << " <none> (non-compliant)";
}
if (pcm_format_set.frame_rates()) {
const auto& frame_rates = *pcm_format_set.frame_rates();
FX_LOGS(INFO) << " frame_rates [" << frame_rates.size() << "]";
for (auto idx = 0u; idx < frame_rates.size(); ++idx) {
FX_LOGS(INFO) << " [" << idx << "] " << frame_rates[idx];
}
} else {
FX_LOGS(INFO) << " <none> (non-compliant)";
}
}
}
void LogGainState(const fuchsia_hardware_audio::GainState& gain_state) {
if constexpr (!kLogStreamConfigFidlResponseValues) {
return;
}
FX_LOGS(INFO) << "fuchsia_hardware_audio/GainState";
FX_LOGS(INFO) << " muted "
<< (gain_state.muted() ? (*gain_state.muted() ? "TRUE" : "FALSE")
: "<none> (Unmuted)");
FX_LOGS(INFO) << " agc_enabled "
<< (gain_state.agc_enabled() ? (*gain_state.agc_enabled() ? "TRUE" : "FALSE")
: "<none> (Disabled)");
if (gain_state.gain_db()) {
FX_LOGS(INFO) << " gain_db " << *gain_state.gain_db() << " dB";
} else {
FX_LOGS(INFO) << " gain_db <none> (non-compliant)";
}
}
void LogPlugState(const fuchsia_hardware_audio::PlugState& plug_state) {
if constexpr (!kLogStreamConfigFidlResponseValues) {
return;
}
FX_LOGS(INFO) << "fuchsia_hardware_audio/PlugState";
FX_LOGS(INFO) << " plugged "
<< (plug_state.plugged() ? (*plug_state.plugged() ? "TRUE" : "FALSE")
: "<none> (non-compliant)");
FX_LOGS(INFO) << " plug_state_time "
<< (plug_state.plug_state_time() ? std::to_string(*plug_state.plug_state_time())
: "<none> (non-compliant)");
}
void LogCodecProperties(const fuchsia_hardware_audio::CodecProperties& codec_props) {
if constexpr (!kLogCodecFidlResponseValues) {
return;
}
FX_LOGS(INFO) << "fuchsia_hardware_audio/CodecProperties";
FX_LOGS(INFO) << " is_input "
<< (codec_props.is_input() ? (*codec_props.is_input() ? "TRUE" : "FALSE")
: "<none> (non-compliant)");
FX_LOGS(INFO) << " manufacturer "
<< (codec_props.manufacturer() ? ("'" +
std::string(codec_props.manufacturer()->data(),
codec_props.manufacturer()->size()) +
"'")
: "<none>");
FX_LOGS(INFO) << " product "
<< (codec_props.product() ? ("'" +
std::string(codec_props.product()->data(),
codec_props.product()->size()) +
"'")
: "<none>");
FX_LOGS(INFO) << " unique_id " << UidToString(codec_props.unique_id());
if (codec_props.plug_detect_capabilities()) {
FX_LOGS(INFO) << " plug_detect_caps " << *codec_props.plug_detect_capabilities();
} else {
FX_LOGS(INFO) << " plug_detect_caps <none> (non-compliant)";
}
}
void LogElementDaiFormatSets(
const std::vector<fuchsia_audio_device::ElementDaiFormatSet>& element_dai_format_sets) {
if constexpr (!kLogCodecFidlResponseValues && !kLogCompositeFidlResponseValues) {
return;
}
for (const auto& element_dai_format_set : element_dai_format_sets) {
LogElementDaiFormatSet(element_dai_format_set);
}
}
void LogElementDaiFormatSet(
const fuchsia_audio_device::ElementDaiFormatSet& element_dai_format_set) {
if constexpr (!kLogCodecFidlResponseValues && !kLogCompositeFidlResponseValues) {
return;
}
if (element_dai_format_set.element_id()) {
FX_LOGS(INFO) << " .element_id " << *element_dai_format_set.element_id();
} else {
FX_LOGS(INFO) << " .element_id <none> (non-compliant)";
}
if (element_dai_format_set.format_sets()) {
FX_LOGS(INFO) << " .format_set [" << element_dai_format_set.format_sets()->size() << "]";
LogDaiFormatSets(*element_dai_format_set.format_sets());
} else {
FX_LOGS(INFO) << " .format_set <none> (non-compliant)";
}
}
void LogDaiFormatSets(
const std::vector<fuchsia_hardware_audio::DaiSupportedFormats>& dai_format_sets) {
if constexpr (!kLogCodecFidlResponseValues) {
return;
}
FX_LOGS(INFO) << "fuchsia_hardware_audio/DaiSupportedFormats";
FX_LOGS(INFO) << " dai_supported_formats [" << dai_format_sets.size() << "]";
for (auto idx = 0u; idx < dai_format_sets.size(); ++idx) {
auto dai_format_set = dai_format_sets[idx];
FX_LOGS(INFO) << " [" << idx << "]";
const auto& channel_counts = dai_format_set.number_of_channels();
FX_LOGS(INFO) << " number_of_channels [" << channel_counts.size() << "]";
for (auto idx = 0u; idx < channel_counts.size(); ++idx) {
FX_LOGS(INFO) << " [" << idx << "] " << channel_counts[idx];
}
const auto& sample_formats = dai_format_set.sample_formats();
FX_LOGS(INFO) << " sample_formats [" << sample_formats.size() << "]";
for (auto idx = 0u; idx < sample_formats.size(); ++idx) {
FX_LOGS(INFO) << " [" << idx << "] " << sample_formats[idx];
}
const auto& frame_formats = dai_format_set.frame_formats();
FX_LOGS(INFO) << " frame_formats [" << frame_formats.size() << "]";
for (auto idx = 0u; idx < frame_formats.size(); ++idx) {
FX_LOGS(INFO) << " [" << idx << "] " << frame_formats[idx];
}
const auto& frame_rates = dai_format_set.frame_rates();
FX_LOGS(INFO) << " frame_rates [" << frame_rates.size() << "]";
for (auto idx = 0u; idx < frame_rates.size(); ++idx) {
FX_LOGS(INFO) << " [" << idx << "] " << frame_rates[idx];
}
const auto& bits_per_slot = dai_format_set.bits_per_slot();
FX_LOGS(INFO) << " bits_per_slot [" << bits_per_slot.size() << "]";
for (auto idx = 0u; idx < bits_per_slot.size(); ++idx) {
FX_LOGS(INFO) << " [" << idx << "] " << static_cast<int16_t>(bits_per_slot[idx]);
}
const auto& bits_per_sample = dai_format_set.bits_per_sample();
FX_LOGS(INFO) << " bits_per_sample [" << bits_per_sample.size() << "]";
for (auto idx = 0u; idx < bits_per_sample.size(); ++idx) {
FX_LOGS(INFO) << " [" << idx << "] "
<< static_cast<int16_t>(bits_per_sample[idx]);
}
}
}
void LogDaiFormat(std::optional<fuchsia_hardware_audio::DaiFormat> dai_format) {
if constexpr (!kLogCodecFidlResponseValues) {
return;
}
FX_LOGS(INFO) << "fuchsia_hardware_audio/DaiFormat";
if (!dai_format) {
FX_LOGS(INFO) << " UNSET";
return;
}
FX_LOGS(INFO) << " number_of_channels " << dai_format->number_of_channels();
FX_LOGS(INFO) << " channels_to_use_bitmask " << std::hex
<< dai_format->channels_to_use_bitmask();
FX_LOGS(INFO) << " sample_format " << dai_format->sample_format();
FX_LOGS(INFO) << " frame_format " << dai_format->frame_format();
FX_LOGS(INFO) << " frame_rate " << dai_format->frame_rate();
FX_LOGS(INFO) << " bits_per_slot "
<< static_cast<uint16_t>(dai_format->bits_per_slot());
FX_LOGS(INFO) << " bits_per_sample "
<< static_cast<uint16_t>(dai_format->bits_per_sample());
}
void LogCodecFormatInfo(std::optional<fuchsia_hardware_audio::CodecFormatInfo> format_info) {
if constexpr (!kLogCodecFidlResponseValues) {
return;
}
FX_LOGS(INFO) << "fuchsia_hardware_audio/CodecFormatInfo";
if (!format_info) {
FX_LOGS(INFO) << " UNSET";
return;
}
FX_LOGS(INFO) << " external_delay (ns) "
<< (format_info->external_delay() ? std::to_string(*format_info->external_delay())
: "<none>");
FX_LOGS(INFO) << " turn_on_delay (ns) "
<< (format_info->turn_on_delay() ? std::to_string(*format_info->turn_on_delay())
: "<none>");
FX_LOGS(INFO) << " turn_off_delay (ns) "
<< (format_info->turn_off_delay() ? std::to_string(*format_info->turn_off_delay())
: "<none>");
}
void LogCompositeProperties(const fuchsia_hardware_audio::CompositeProperties& composite_props) {
if constexpr (!kLogCompositeFidlResponseValues) {
return;
}
FX_LOGS(INFO) << "fuchsia_hardware_audio/CompositeProperties";
FX_LOGS(INFO) << " manufacturer "
<< (composite_props.manufacturer()
? ("'" +
std::string(composite_props.manufacturer()->data(),
composite_props.manufacturer()->size()) +
"'")
: "<none>");
FX_LOGS(INFO) << " product "
<< (composite_props.product() ? ("'" +
std::string(composite_props.product()->data(),
composite_props.product()->size()) +
"'")
: "<none>");
FX_LOGS(INFO) << " unique_id " << UidToString(composite_props.unique_id());
if (composite_props.clock_domain()) {
FX_LOGS(INFO) << " clock_domain " << *composite_props.clock_domain();
} else {
FX_LOGS(INFO) << " clock_domain <none> (non-compliant)";
}
}
void LogElementStateInternal(
const std::optional<fuchsia_hardware_audio_signalprocessing::ElementState>& element_state,
const std::string& indent) {
if (!element_state.has_value()) {
FX_LOGS(INFO) << indent << " <none> (during device initialization)";
return;
}
if (element_state->type_specific().has_value()) {
switch (element_state->type_specific()->Which()) {
case fuchsia_hardware_audio_signalprocessing::TypeSpecificElementState::Tag::kVendorSpecific:
FX_LOGS(INFO) << indent << "type_specific VendorSpecific";
break;
case fuchsia_hardware_audio_signalprocessing::TypeSpecificElementState::Tag::kGain:
FX_LOGS(INFO) << indent << "type_specific Gain";
break;
case fuchsia_hardware_audio_signalprocessing::TypeSpecificElementState::Tag::kEqualizer:
FX_LOGS(INFO) << indent << "type_specific Equalizer";
break;
case fuchsia_hardware_audio_signalprocessing::TypeSpecificElementState::Tag::kDynamics:
FX_LOGS(INFO) << indent << "type_specific Dynamics";
break;
case fuchsia_hardware_audio_signalprocessing::TypeSpecificElementState::Tag::kEndpoint:
FX_LOGS(INFO) << indent << "type_specific Endpoint";
break;
default:
FX_LOGS(INFO) << indent << "type_specific <unknown union> (non-compliant)";
break;
}
} else {
FX_LOGS(INFO) << indent << "type_specific <none>";
}
FX_LOGS(INFO) << indent << "enabled "
<< (element_state->enabled().has_value()
? (*element_state->enabled() ? "TRUE" : "FALSE")
: "<none>");
if (element_state->latency().has_value()) {
switch (element_state->latency()->Which()) {
case fuchsia_hardware_audio_signalprocessing::Latency::Tag::kLatencyTime:
FX_LOGS(INFO) << indent << "latency (time)";
if (element_state->latency()->latency_time().has_value()) {
FX_LOGS(INFO) << indent << " "
<< element_state->latency()->latency_time().value() << " ns";
} else {
FX_LOGS(INFO) << indent << " <none> ns (non-compliant)";
}
break;
case fuchsia_hardware_audio_signalprocessing::Latency::Tag::kLatencyFrames:
FX_LOGS(INFO) << indent << "latency (frames)";
if (element_state->latency()->latency_frames().has_value()) {
FX_LOGS(INFO) << indent << " "
<< element_state->latency()->latency_frames().value() << " frames";
} else {
FX_LOGS(INFO) << indent << " <none> frames (non-compliant)";
}
break;
default:
FX_LOGS(INFO) << indent << "latency <unknown union> ( non-compliant)";
break;
}
} else {
FX_LOGS(INFO) << indent << "latency <none>";
}
if (element_state->vendor_specific_data().has_value()) {
FX_LOGS(INFO) << indent << "vendor_specific_data ["
<< element_state->vendor_specific_data()->size() << "] (not shown here)"
<< (element_state->vendor_specific_data()->empty() ? " (non-compliant)" : "");
} else {
FX_LOGS(INFO) << indent << "vendor_specific_data <none>";
}
}
void LogElementState(
const std::optional<fuchsia_hardware_audio_signalprocessing::ElementState>& element_state) {
if constexpr (!kLogSignalProcessingFidlResponseValues) {
return;
}
FX_LOGS(INFO) << "fuchsia_hardware_audio_signalprocessing/ElementState";
LogElementStateInternal(element_state, " ");
}
void LogElementInternal(const fuchsia_hardware_audio_signalprocessing::Element& element,
std::string indent, std::optional<size_t> index = std::nullopt,
std::string_view addl_indent = "") {
std::string first_indent{indent};
if (index.has_value()) {
first_indent.append("[")
.append(std::to_string(*index))
.append("]")
.append(addl_indent.substr(3));
} else {
first_indent.append(addl_indent);
}
indent.append(addl_indent);
FX_LOGS(INFO) << first_indent << "id "
<< (element.id() ? std::to_string(*element.id()) : "<none> (non-compliant)");
FX_LOGS(INFO) << indent << "type " << element.type();
std::ostringstream type_specific;
type_specific << "type_specific ";
if (element.type_specific()) {
switch (element.type_specific()->Which()) {
case fuchsia_hardware_audio_signalprocessing::TypeSpecificElement::Tag::kVendorSpecific:
type_specific << "vendor_specific";
break;
case fuchsia_hardware_audio_signalprocessing::TypeSpecificElement::Tag::kGain:
type_specific << "gain";
break;
case fuchsia_hardware_audio_signalprocessing::TypeSpecificElement::Tag::kEqualizer:
type_specific << "equalizer";
break;
case fuchsia_hardware_audio_signalprocessing::TypeSpecificElement::Tag::kDynamics:
type_specific << "dynamics";
break;
case fuchsia_hardware_audio_signalprocessing::TypeSpecificElement::Tag::kEndpoint:
type_specific << element.type_specific()->endpoint().value();
break;
default:
type_specific << "OTHER (unknown enum)";
break;
}
} else {
type_specific << "<none>";
}
FX_LOGS(INFO) << indent << type_specific.str();
FX_LOGS(INFO) << indent << "can_disable "
<< (element.can_disable() ? (*element.can_disable() ? "TRUE" : "FALSE")
: "<none> (FALSE)");
FX_LOGS(INFO) << indent << "description "
<< (element.description() ? std::string("'") + *element.description() + "'"
: "<none>");
}
void LogElement(const fuchsia_hardware_audio_signalprocessing::Element& element) {
if constexpr (!kLogSignalProcessingFidlResponseValues) {
return;
}
FX_LOGS(INFO) << "fuchsia_hardware_audio_signalprocessing/Element";
LogElementInternal(element, " ");
}
void LogElements(const std::vector<fuchsia_hardware_audio_signalprocessing::Element>& elements) {
if constexpr (!kLogSignalProcessingFidlResponseValues) {
return;
}
FX_LOGS(INFO) << "fuchsia_hardware_audio_signalprocessing/Elements";
FX_LOGS(INFO) << " elements [" << elements.size() << "]";
for (auto i = 0u; i < elements.size(); ++i) {
LogElementInternal(elements[i], " ", i, " ");
}
}
void LogElementMap(const std::unordered_map<ElementId, ElementRecord>& element_map) {
if constexpr (!kLogSignalProcessingFidlResponseValues) {
return;
}
FX_LOGS(INFO) << "ElementMap <ElementId, ElementRecord>";
for (auto& [element_id, element_record] : element_map) {
FX_LOGS(INFO) << "ElementId " << element_id;
FX_LOGS(INFO) << "ElementRecord";
FX_LOGS(INFO) << " element";
LogElementInternal(element_record.element, " ");
FX_LOGS(INFO) << " state";
LogElementStateInternal(element_record.state, " ");
}
}
void LogTopologyInternal(const fuchsia_hardware_audio_signalprocessing::Topology& topology,
std::string indent, std::optional<size_t> index = std::nullopt,
std::string_view addl_indent = "") {
std::string first_indent{indent};
if (index.has_value()) {
first_indent.append("[")
.append(std::to_string(*index))
.append("]")
.append(addl_indent.substr(3));
} else {
first_indent.append(addl_indent);
}
indent.append(addl_indent);
FX_LOGS(INFO) << first_indent << "id "
<< (topology.id() ? std::to_string(*topology.id()) : "<none> (non-compliant)");
if (topology.processing_elements_edge_pairs()) {
FX_LOGS(INFO) << indent << "processing_elements_edge_pairs ["
<< topology.processing_elements_edge_pairs()->size() << "]";
for (auto idx = 0u; idx < topology.processing_elements_edge_pairs()->size(); ++idx) {
FX_LOGS(INFO)
<< indent << " [" << idx << "] "
<< topology.processing_elements_edge_pairs()->at(idx).processing_element_id_from()
<< " -> "
<< topology.processing_elements_edge_pairs()->at(idx).processing_element_id_to();
}
} else {
FX_LOGS(INFO) << indent << "processing_elements_edge_pairs <none> (non-compliant)";
}
}
void LogTopology(const fuchsia_hardware_audio_signalprocessing::Topology& topology) {
if constexpr (!kLogSignalProcessingFidlResponseValues) {
return;
}
FX_LOGS(INFO) << "fuchsia_hardware_audio_signalprocessing/Topology";
LogTopologyInternal(topology, " ");
}
void LogTopologies(
const std::vector<fuchsia_hardware_audio_signalprocessing::Topology>& topologies) {
if constexpr (!kLogSignalProcessingFidlResponseValues) {
return;
}
FX_LOGS(INFO) << "fuchsia_hardware_audio_signalprocessing/Topologies";
FX_LOGS(INFO) << " topologies [" << topologies.size() << "]";
for (auto idx = 0u; idx < topologies.size(); ++idx) {
LogTopologyInternal(topologies[idx], " ", idx, " ");
}
}
// Signal the successful detection, querying, initialization and addition of a device.
void LogDeviceAddition(const fuchsia_audio_device::Info& device_info) {
if constexpr (kLogDeviceAddErrorRemove) {
FX_DCHECK(device_info.device_type().has_value());
FX_LOGS(INFO) << device_info.device_type() << " device "
<< (device_info.device_name()
? std::string("'") + *device_info.device_name() + "'"
: "<none>")
<< " with token_id "
<< (device_info.token_id() ? std::to_string(*device_info.token_id())
: "<none> (non-compliant)")
<< " has been added";
}
}
// Mirror (bookend) the analogous `LogDeviceAddition` for device removal. Removals may be "normal"
// (USB unplug) or caused by fatal error. The latter can happen before `device_info` is created.
void LogDeviceRemoval(const std::optional<fuchsia_audio_device::Info>& device_info) {
if constexpr (kLogDeviceAddErrorRemove) {
if (device_info.has_value()) {
FX_DCHECK(device_info->device_type().has_value());
FX_LOGS(INFO) << device_info->device_type() << " device "
<< (device_info->device_name()
? std::string("'") + *device_info->device_name() + "'"
: "<none>")
<< " with token_id "
<< (device_info->token_id() ? std::to_string(*device_info->token_id())
: "<none> (non-compliant)")
<< " has been removed";
} else {
FX_LOGS(WARNING) << "UNKNOWN (uninitialized) device has encountered a fatal error";
}
}
}
// Mirror (bookend) the analogous `LogDeviceAddition`, for a device error.
// This can also occur before a device has been successfully added: device_info may not be set.
void LogDeviceError(const std::optional<fuchsia_audio_device::Info>& device_info) {
if constexpr (kLogDeviceAddErrorRemove) {
if (device_info.has_value()) {
FX_DCHECK(device_info->device_type().has_value());
FX_LOGS(WARNING) << device_info->device_type() << " device "
<< (device_info->device_name().has_value()
? std::string("'") + *device_info->device_name() + "'"
: "<none>")
<< " with token_id "
<< (device_info->token_id() ? std::to_string(*device_info->token_id())
: "<none> (non-compliant)")
<< " has encountered a fatal error";
} else {
FX_LOGS(WARNING) << "UNKNOWN (uninitialized) device has encountered a fatal error";
}
}
}
void LogDeviceInfo(const fuchsia_audio_device::Info& device_info) {
if constexpr (!kLogDeviceInfo) {
return;
}
FX_LOGS(INFO) << "fuchsia_audio_device/Info";
FX_LOGS(INFO) << " token_id "
<< (device_info.token_id() ? std::to_string(*device_info.token_id())
: "<none> (non-compliant)");
FX_LOGS(INFO) << " device_type " << device_info.device_type();
FX_LOGS(INFO) << " device_name "
<< (device_info.device_name() ? std::string("'") + *device_info.device_name() + "'"
: "<none>");
FX_LOGS(INFO) << " manufacturer "
<< (device_info.manufacturer() ? "'" + *device_info.manufacturer() + "'"
: "<none>");
FX_LOGS(INFO) << " product "
<< (device_info.product() ? "'" + *device_info.product() + "'" : "<none>");
FX_LOGS(INFO) << " unique_instance_id "
<< UidToString(device_info.unique_instance_id());
FX_LOGS(INFO) << " is_input "
<< (device_info.is_input() ? (*device_info.is_input() ? "TRUE" : "FALSE")
: "<none>");
if (device_info.ring_buffer_format_sets()) {
FX_LOGS(INFO) << " ring_buffer_format_sets [" << device_info.ring_buffer_format_sets()->size()
<< "]";
for (auto i = 0u; i < device_info.ring_buffer_format_sets()->size(); ++i) {
const auto& element_ring_buffer_format_set = device_info.ring_buffer_format_sets()->at(i);
FX_LOGS(INFO) << " [" << i << "] element_id "
<< (element_ring_buffer_format_set.element_id().has_value()
? std::to_string(*element_ring_buffer_format_set.element_id())
: "<none> (non-compliant)");
if (element_ring_buffer_format_set.format_sets().has_value()) {
FX_LOGS(INFO) << " format_set ["
<< element_ring_buffer_format_set.format_sets()->size() << "]";
for (auto j = 0u; j < element_ring_buffer_format_set.format_sets()->size(); ++j) {
const auto& pcm_format_set = element_ring_buffer_format_set.format_sets()->at(j);
if (pcm_format_set.channel_sets()) {
FX_LOGS(INFO) << " [" << j << "] channel_sets ["
<< pcm_format_set.channel_sets()->size() << "]";
for (auto k = 0u; k < pcm_format_set.channel_sets()->size(); ++k) {
const auto& channel_set = pcm_format_set.channel_sets()->at(k);
if (channel_set.attributes()) {
FX_LOGS(INFO) << " [" << k << "] attributes ["
<< channel_set.attributes()->size() << "]";
for (auto idx = 0u; idx < channel_set.attributes()->size(); ++idx) {
const auto& attributes = channel_set.attributes()->at(idx);
if (attributes.min_frequency()) {
FX_LOGS(INFO) << " [" << idx << "] min_freq "
<< *attributes.min_frequency();
} else {
FX_LOGS(INFO) << " [" << idx << "] min_freq <none>";
}
if (attributes.max_frequency()) {
FX_LOGS(INFO) << " max_freq "
<< *attributes.max_frequency();
} else {
FX_LOGS(INFO) << " max_freq <none>";
}
}
} else {
FX_LOGS(INFO) << " [" << k
<< "] attributes <none> (non-compliant)";
}
}
} else {
FX_LOGS(INFO) << " [" << j << "] channel_sets <none> (non-compliant)";
}
if (pcm_format_set.sample_types()) {
FX_LOGS(INFO) << " sample_types [" << pcm_format_set.sample_types()->size()
<< "]";
for (auto idx = 0u; idx < pcm_format_set.sample_types()->size(); ++idx) {
FX_LOGS(INFO) << " [" << idx << "] "
<< pcm_format_set.sample_types()->at(idx);
}
} else {
FX_LOGS(INFO) << " sample_types <none> (non-compliant)";
}
if (pcm_format_set.frame_rates()) {
FX_LOGS(INFO) << " frame_rates [" << pcm_format_set.frame_rates()->size()
<< "]";
for (auto idx = 0u; idx < pcm_format_set.frame_rates()->size(); ++idx) {
FX_LOGS(INFO) << " [" << idx << "] "
<< pcm_format_set.frame_rates()->at(idx);
}
} else {
FX_LOGS(INFO) << " frame_rates <none> (non-compliant)";
}
}
} else {
FX_LOGS(INFO) << " format_set <none> (non-compliant)";
}
}
} else {
FX_LOGS(INFO) << " ring_buffer_format_sets <none>"
<< ((device_info.device_type() == fuchsia_audio_device::DeviceType::kInput ||
device_info.device_type() == fuchsia_audio_device::DeviceType::kOutput)
? " (non-compliant)"
: "");
}
// dai_format_sets
if (device_info.dai_format_sets()) {
FX_LOGS(INFO) << " dai_format_sets [" << device_info.dai_format_sets()->size() << "]";
for (auto i = 0u; i < device_info.dai_format_sets()->size(); ++i) {
auto element_dai_format_set = device_info.dai_format_sets()->at(i);
FX_LOGS(INFO) << " [" << i << "] element_id "
<< (element_dai_format_set.format_sets().has_value()
? std::to_string(*element_dai_format_set.element_id())
: "<none> (non-compliant)");
if (element_dai_format_set.format_sets().has_value()) {
FX_LOGS(INFO) << " format_set [" << element_dai_format_set.format_sets()->size()
<< "]";
for (auto j = 0u; j < element_dai_format_set.format_sets()->size(); ++j) {
const auto& dai_format_set = element_dai_format_set.format_sets()->at(j);
const auto& channel_counts = dai_format_set.number_of_channels();
FX_LOGS(INFO) << " [" << j << "] number_of_channels [" << channel_counts.size()
<< "]";
for (auto idx = 0u; idx < channel_counts.size(); ++idx) {
FX_LOGS(INFO) << " [" << idx << "] " << channel_counts[idx];
}
const auto& sample_formats = dai_format_set.sample_formats();
FX_LOGS(INFO) << " sample_formats [" << sample_formats.size() << "]";
for (auto idx = 0u; idx < sample_formats.size(); ++idx) {
FX_LOGS(INFO) << " [" << idx << "] " << sample_formats[idx];
}
const auto& frame_formats = dai_format_set.frame_formats();
FX_LOGS(INFO) << " frame_formats [" << frame_formats.size() << "]";
for (auto idx = 0u; idx < frame_formats.size(); ++idx) {
FX_LOGS(INFO) << " [" << idx << "] " << frame_formats[idx];
}
const auto& frame_rates = dai_format_set.frame_rates();
FX_LOGS(INFO) << " frame_rates [" << frame_rates.size() << "]";
for (auto idx = 0u; idx < frame_rates.size(); ++idx) {
FX_LOGS(INFO) << " [" << idx << "] " << frame_rates[idx];
}
const auto& bits_per_slot = dai_format_set.bits_per_slot();
FX_LOGS(INFO) << " bits_per_slot [" << bits_per_slot.size() << "]";
for (auto idx = 0u; idx < bits_per_slot.size(); ++idx) {
FX_LOGS(INFO) << " [" << idx << "] "
<< static_cast<int16_t>(bits_per_slot[idx]);
}
const auto& bits_per_sample = dai_format_set.bits_per_sample();
FX_LOGS(INFO) << " bits_per_sample [" << bits_per_sample.size() << "]";
for (auto idx = 0u; idx < bits_per_sample.size(); ++idx) {
FX_LOGS(INFO) << " [" << idx << "] "
<< static_cast<int16_t>(bits_per_sample[idx]);
}
}
} else {
FX_LOGS(INFO) << " format_set <none> (non-compliant)";
}
}
} else {
FX_LOGS(INFO) << " dai_format_sets <none>"
<< ((device_info.device_type() == fuchsia_audio_device::DeviceType::kCodec)
? " (non-compliant)"
: "");
}
if (device_info.gain_caps()) {
if (device_info.gain_caps()->min_gain_db()) {
FX_LOGS(INFO) << " gain_caps min_gain_db " << *device_info.gain_caps()->min_gain_db()
<< " dB";
} else {
FX_LOGS(INFO) << " gain_caps min_gain_db <none> (non-compliant)";
}
if (device_info.gain_caps()->max_gain_db()) {
FX_LOGS(INFO) << " max_gain_db " << *device_info.gain_caps()->max_gain_db()
<< " dB";
} else {
FX_LOGS(INFO) << " max_gain_db <none> (non-compliant)";
}
if (device_info.gain_caps()->gain_step_db()) {
FX_LOGS(INFO) << " gain_step_db "
<< *device_info.gain_caps()->gain_step_db() << " dB";
} else {
FX_LOGS(INFO) << " gain_step_db <none> (non-compliant)";
}
FX_LOGS(INFO) << " can_mute "
<< (device_info.gain_caps()->can_mute()
? (*device_info.gain_caps()->can_mute() ? "true" : "false")
: "<none> (false)");
FX_LOGS(INFO) << " can_agc "
<< (device_info.gain_caps()->can_agc()
? (*device_info.gain_caps()->can_agc() ? "true" : "false")
: "<none> (false)");
} else {
FX_LOGS(INFO) << " gain_caps <none>"
<< ((device_info.device_type() == fuchsia_audio_device::DeviceType::kInput ||
device_info.device_type() == fuchsia_audio_device::DeviceType::kOutput)
? " (non-compliant)"
: "");
}
FX_LOGS(INFO) << " plug_detect_caps " << device_info.plug_detect_caps();
std::string clock_domain_str{" clock_domain "};
if (device_info.clock_domain()) {
clock_domain_str += std::to_string(*device_info.clock_domain());
if (*device_info.clock_domain() == fuchsia_hardware_audio::kClockDomainMonotonic) {
clock_domain_str += " (CLOCK_DOMAIN_MONOTONIC)";
} else if (*device_info.clock_domain() == fuchsia_hardware_audio::kClockDomainExternal) {
clock_domain_str += " (CLOCK_DOMAIN_EXTERNAL)";
}
} else {
clock_domain_str += "<none>";
if (device_info.device_type() == fuchsia_audio_device::DeviceType::kComposite ||
device_info.device_type() == fuchsia_audio_device::DeviceType::kInput ||
device_info.device_type() == fuchsia_audio_device::DeviceType::kOutput) {
clock_domain_str += " (non-compliant)";
}
}
FX_LOGS(INFO) << clock_domain_str;
if (device_info.signal_processing_elements()) {
FX_LOGS(INFO) << " signal_processing_elements ["
<< device_info.signal_processing_elements()->size() << "]"
<< (device_info.signal_processing_elements()->empty() ? " (non-compliant)" : "");
for (auto idx = 0u; idx < device_info.signal_processing_elements()->size(); ++idx) {
LogElementInternal(device_info.signal_processing_elements()->at(idx), " ", idx,
" ");
}
} else {
FX_LOGS(INFO) << " signal_processing_elements <none>"
<< (device_info.device_type() == fuchsia_audio_device::DeviceType::kComposite
? " (non-compliant)"
: "");
}
if (device_info.signal_processing_topologies()) {
FX_LOGS(INFO) << " signal_processing_topologies ["
<< device_info.signal_processing_topologies()->size() << "]"
<< (device_info.signal_processing_topologies()->empty() ? " (non-compliant)"
: "");
for (auto idx = 0u; idx < device_info.signal_processing_topologies()->size(); ++idx) {
LogTopologyInternal(device_info.signal_processing_topologies()->at(idx), " ", idx,
" ");
}
} else {
FX_LOGS(INFO) << " signal_processing_topologies <none>"
<< (device_info.device_type() == fuchsia_audio_device::DeviceType::kComposite
? " (non-compliant)"
: "");
}
}
void LogRingBufferProperties(const fuchsia_hardware_audio::RingBufferProperties& rb_props) {
if constexpr (!kLogRingBufferFidlResponseValues) {
return;
}
FX_LOGS(INFO) << "fuchsia_hardware_audio/RingBufferProperties";
FX_LOGS(INFO) << " needs_cache_flush "
<< (rb_props.needs_cache_flush_or_invalidate()
? (*rb_props.needs_cache_flush_or_invalidate() ? "TRUE" : "FALSE")
: "<none> (non-compliant)");
if (rb_props.turn_on_delay()) {
FX_LOGS(INFO) << " turn_on_delay " << *rb_props.turn_on_delay() << " ns";
} else {
FX_LOGS(INFO) << " turn_on_delay <none> (0 ns)";
}
if (rb_props.driver_transfer_bytes()) {
FX_LOGS(INFO) << " driver_transfer_bytes " << *rb_props.driver_transfer_bytes()
<< " bytes";
} else {
FX_LOGS(INFO) << " driver_transfer_bytes <none> (non-compliant)";
}
}
void LogRingBufferFormat(const fuchsia_hardware_audio::Format& ring_buffer_format) {
if constexpr (!kLogRingBufferFidlResponseValues) {
return;
}
FX_LOGS(INFO) << "fuchsia_hardware_audio/Format";
if (!ring_buffer_format.pcm_format()) {
FX_LOGS(INFO) << " pcm_format <none> (non-compliant)";
return;
}
FX_LOGS(INFO) << " pcm_format";
FX_LOGS(INFO) << " number_of_channels "
<< static_cast<uint16_t>(ring_buffer_format.pcm_format()->number_of_channels());
FX_LOGS(INFO) << " sample_format "
<< ring_buffer_format.pcm_format()->sample_format();
FX_LOGS(INFO) << " bytes_per_sample "
<< static_cast<uint16_t>(ring_buffer_format.pcm_format()->bytes_per_sample());
FX_LOGS(INFO) << " valid_bits_per_sample "
<< static_cast<uint16_t>(ring_buffer_format.pcm_format()->valid_bits_per_sample());
FX_LOGS(INFO) << " frame_rate "
<< ring_buffer_format.pcm_format()->frame_rate();
}
void LogRingBufferVmo(const zx::vmo& vmo, uint32_t num_frames,
fuchsia_hardware_audio::Format rb_format) {
if constexpr (!kLogRingBufferFidlResponseValues) {
return;
}
zx_info_handle_basic_t info;
auto status = vmo.get_info(ZX_INFO_HANDLE_BASIC, &info, sizeof(info), nullptr, nullptr);
if (status != ZX_OK) {
FX_PLOGS(WARNING, status) << "vmo.get_info returned error";
return;
}
uint64_t size;
status = vmo.get_size(&size);
if (status != ZX_OK) {
FX_PLOGS(WARNING, status) << "vmo.get_size returned size " << size;
return;
}
FX_LOGS(INFO) << "fuchsia_hardware_audio/Vmo";
FX_LOGS(INFO) << " koid 0x" << std::hex << info.koid;
FX_LOGS(INFO) << " size " << size << " bytes";
FX_LOGS(INFO) << " calculated_size "
<< num_frames * rb_format.pcm_format()->number_of_channels() *
rb_format.pcm_format()->bytes_per_sample();
FX_LOGS(INFO) << " num_frames " << num_frames;
FX_LOGS(INFO) << " num_channels "
<< static_cast<uint16_t>(rb_format.pcm_format()->number_of_channels());
FX_LOGS(INFO) << " bytes_per_sample "
<< static_cast<uint16_t>(rb_format.pcm_format()->bytes_per_sample());
}
void LogActiveChannels(uint64_t channel_bitmask, zx::time set_time) {
if constexpr (!kLogRingBufferFidlResponseValues) {
return;
}
FX_LOGS(INFO) << "fuchsia_hardware_audio/SetActiveChannels";
FX_LOGS(INFO) << " channel_bitmask 0x" << std::setfill('0') << std::setw(2) << std::hex
<< channel_bitmask;
FX_LOGS(INFO) << " set_time " << set_time.get();
}
void LogDelayInfo(const fuchsia_hardware_audio::DelayInfo& info) {
if constexpr (!kLogRingBufferFidlResponseValues) {
return;
}
FX_LOGS(INFO) << "fuchsia_hardware_audio/DelayInfo";
if (info.internal_delay()) {
FX_LOGS(INFO) << " internal_delay " << *info.internal_delay() << " ns";
} else {
FX_LOGS(INFO) << " internal_delay <none> (non-compliant)";
}
if (info.external_delay()) {
FX_LOGS(INFO) << " external_delay " << *info.external_delay() << " ns";
} else {
FX_LOGS(INFO) << " external_delay <none> (0 ns)";
}
}
void LogObjectCounts() {
ADR_LOG(kLogObjectCounts) << Device::count() << " Devices (" << Device::initialized_count()
<< " active/" << Device::unhealthy_count() << " unhealthy); "
<< ProviderServer::count() << " Prov, " << RegistryServer::count()
<< " Reg, " << ObserverServer::count() << " Obs, "
<< ControlCreatorServer::count() << " CtlCreators, "
<< ControlServer::count() << " Ctls, " << RingBufferServer::count()
<< " RingBuffs";
}
} // namespace media_audio