1 // Copyright 2018 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #pragma once 6 7 #include <fbl/macros.h> 8 #include <fbl/intrusive_double_list.h> 9 #include <fbl/unique_ptr.h> 10 11 #include <utility> 12 13 #include "usb-audio.h" 14 #include "usb-audio-units.h" 15 16 namespace audio { 17 namespace usb { 18 19 class UsbAudioControlInterface; 20 21 // A small container class used by the audio control interface for describing a 22 // path through the unit/terminal graph from host to pin (or vice-versa) 23 class AudioPath : public fbl::DoublyLinkedListable<fbl::unique_ptr<AudioPath>> { 24 public: direction()25 Direction direction() const { return direction_; } stream_terminal()26 const Terminal& stream_terminal() const { 27 // If we do not have a stashed pointer to our terminal yet, then someone 28 // is calling this accessor before Setup completed successfully. This 29 // should never happen. 30 ZX_DEBUG_ASSERT(stream_terminal_ != nullptr); 31 return *stream_terminal_; 32 } 33 has_gain()34 bool has_gain() const { return feature_unit_ && feature_unit_->has_vol(); } has_agc()35 bool has_agc() const { return feature_unit_ && feature_unit_->has_agc(); } has_mute()36 bool has_mute() const { return feature_unit_ && feature_unit_->has_mute(); } cur_gain()37 float cur_gain() const { return feature_unit_ ? feature_unit_->vol_cur_db() : 0.0f; } min_gain()38 float min_gain() const { return feature_unit_ ? feature_unit_->vol_min_db() : 0.0f; } max_gain()39 float max_gain() const { return feature_unit_ ? feature_unit_->vol_max_db() : 0.0f; } gain_res()40 float gain_res() const { return feature_unit_ ? feature_unit_->vol_res_db() : 0.0f; } cur_agc()41 bool cur_agc() const { return feature_unit_ ? feature_unit_->agc_cur() : false; } cur_mute()42 bool cur_mute() const { return feature_unit_ ? feature_unit_->mute_cur() : false; } 43 SetGain(const usb_protocol_t & proto,float db)44 float SetGain(const usb_protocol_t& proto, float db) { 45 return feature_unit_ ? feature_unit_->SetVol(proto, db) : 0.0f; 46 } 47 SetMute(const usb_protocol_t & proto,bool mute)48 bool SetMute(const usb_protocol_t& proto, bool mute) { 49 return feature_unit_ ? feature_unit_->SetMute(proto, mute) : false; 50 } 51 SetAgc(const usb_protocol_t & proto,bool enabled)52 bool SetAgc(const usb_protocol_t& proto, bool enabled) { 53 return feature_unit_ ? feature_unit_->SetAgc(proto, enabled) : false; 54 } 55 56 private: 57 friend class fbl::unique_ptr<AudioPath>; 58 friend class UsbAudioControlInterface; 59 60 // Methods use by the audio control interface class to build audio paths 61 // during its walk of the unit/terminal graph. Basically, the control 62 // interface class calls... 63 // 64 // 1) 'Create' when it finds what looks like a valid path during its recursive 65 // walk of the graph. 66 // 2) 'AddUnit' as it unwinds from the walk in order to store references 67 // which form the path in the proper order inside of the path. 68 // 3) 'Setup' when it is finished in order to sanity check the path and to 69 // stash pointers to important elements, such as the stream terminal 70 // node and the feature unit node (if found). 71 // 72 static fbl::unique_ptr<AudioPath> Create(uint32_t unit_count); 73 void AddUnit(uint32_t ndx, fbl::RefPtr<AudioUnit> unit); 74 zx_status_t Setup(const usb_protocol_t& proto); 75 AudioPath(fbl::unique_ptr<fbl::RefPtr<AudioUnit>[]> units,uint32_t unit_count)76 AudioPath(fbl::unique_ptr<fbl::RefPtr<AudioUnit>[]> units, uint32_t unit_count) 77 : units_(std::move(units)), unit_count_(unit_count) {} ~AudioPath()78 ~AudioPath() {} 79 80 DISALLOW_COPY_ASSIGN_AND_MOVE(AudioPath); 81 82 const fbl::unique_ptr<fbl::RefPtr<AudioUnit>[]> units_; 83 const uint32_t unit_count_; 84 Direction direction_ = Direction::Unknown; 85 86 // Note: Strictly speaking, these cached references do not have to be 87 // RefPtrs. In theory, the members of units_ should always outlive these 88 // cache references. This said, the cost of holding an extra reference on 89 // the objects is basically zero, and storing the pointers internally as 90 // RefPtr<>s makes it easy to know that this is safe from a lifecycle 91 // perspective, if perhaps a tiny bit paranoid. 92 fbl::RefPtr<const Terminal> stream_terminal_; 93 fbl::RefPtr<FeatureUnit> feature_unit_; 94 }; 95 96 } // namespace usb 97 } // namespace audio 98 99