1 // Copyright 2017 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 <zircon/device/audio.h>
8 #include <zircon/types.h>
9 #include <lib/zx/channel.h>
10 #include <lib/zx/vmo.h>
11 #include <fbl/unique_ptr.h>
12 #include <fbl/vector.h>
13 
14 namespace audio {
15 namespace utils {
16 
17 class AudioDeviceStream {
18 public:
19     zx_status_t Open();
20     zx_status_t GetSupportedFormats(fbl::Vector<audio_stream_format_range_t>* out_formats) const;
21     zx_status_t SetMute(bool mute);
22     zx_status_t SetAgc(bool enabled);
23     zx_status_t SetGain(float gain);
24     zx_status_t GetGain(audio_stream_cmd_get_gain_resp_t* out_gain) const;
25     zx_status_t GetUniqueId(audio_stream_cmd_get_unique_id_resp_t* out_id) const;
26     zx_status_t GetString(audio_stream_string_id_t id,
27                           audio_stream_cmd_get_string_resp_t* out_str) const;
28     zx_status_t PlugMonitor(float duration);
29     zx_status_t SetFormat(uint32_t frames_per_second,
30                           uint16_t channels,
31                           audio_sample_format_t sample_format);
32     zx_status_t GetBuffer(uint32_t frames, uint32_t irqs_per_ring);
33     zx_status_t StartRingBuffer();
34     zx_status_t StopRingBuffer();
35     void        ResetRingBuffer();
36     void        Close();
37 
GetPlugState(audio_stream_cmd_plug_detect_resp_t * out_state)38     zx_status_t GetPlugState(audio_stream_cmd_plug_detect_resp_t* out_state) const {
39         return GetPlugState(out_state, false);
40     }
41 
IsStreamBufChannelConnected()42     bool IsStreamBufChannelConnected() const { return IsChannelConnected(stream_ch_); }
IsRingBufChannelConnected()43     bool IsRingBufChannelConnected() const { return IsChannelConnected(rb_ch_); }
44 
name()45     const char* name()                 const { return name_; }
input()46     bool        input()                const { return input_; }
frame_rate()47     uint32_t    frame_rate()           const { return frame_rate_; }
sample_size()48     uint32_t    sample_size()          const { return sample_size_; }
channel_cnt()49     uint32_t    channel_cnt()          const { return channel_cnt_; }
frame_sz()50     uint32_t    frame_sz()             const { return frame_sz_; }
fifo_depth()51     uint64_t    fifo_depth()           const { return fifo_depth_; }
ring_buffer_bytes()52     uint32_t    ring_buffer_bytes()    const { return rb_sz_; }
ring_buffer()53     void*       ring_buffer()          const { return rb_virt_; }
start_time()54     uint64_t    start_time()           const { return start_time_; }
external_delay_nsec()55     uint64_t    external_delay_nsec()  const { return external_delay_nsec_; }
56 
57 protected:
58     friend class fbl::unique_ptr<AudioDeviceStream>;
59 
60     static bool IsChannelConnected(const zx::channel& ch);
61     zx_status_t GetPlugState(audio_stream_cmd_plug_detect_resp_t* out_state,
62                              bool enable_notify) const;
63     void        DisablePlugNotifications();
64 
65     AudioDeviceStream(bool input, uint32_t dev_id);
66     AudioDeviceStream(bool input, const char* dev_path);
67     virtual ~AudioDeviceStream();
68 
69     zx::channel stream_ch_;
70     zx::channel rb_ch_;
71     zx::vmo     rb_vmo_;
72 
73     const bool  input_;
74     char        name_[64] = { 0 };
75 
76     audio_sample_format_t sample_format_;
77     uint64_t start_time_           = 0;
78     uint64_t external_delay_nsec_  = 0;
79     uint32_t frame_rate_           = 0;
80     uint32_t sample_size_          = 0;
81     uint32_t channel_cnt_          = 0;
82     uint32_t frame_sz_             = 0;
83     uint32_t fifo_depth_           = 0;
84     uint32_t rb_sz_                = 0;
85     void*    rb_virt_              = nullptr;
86 };
87 
88 }  // namespace utils
89 }  // namespace audio
90