blob: 65bded1685b03af662431897ce6dc524720a23de [file] [log] [blame]
// Copyright 2017 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 AUDIO_UTILS_AUDIO_DEVICE_STREAM_H_
#define AUDIO_UTILS_AUDIO_DEVICE_STREAM_H_
#include <fuchsia/hardware/audio/llcpp/fidl.h>
#include <lib/zx/channel.h>
#include <lib/zx/vmo.h>
#include <zircon/device/audio.h>
#include <zircon/types.h>
#include <functional>
#include <memory>
#include <variant>
#include <fbl/vector.h>
#include "duration.h"
namespace audio {
namespace utils {
namespace audio_fidl = ::llcpp::fuchsia::hardware::audio;
class AudioDeviceStream {
public:
enum class StreamDirection {
kInput,
kOutput,
};
using PlugMonitorCallback = std::function<bool(bool plug_state, zx_time_t plug_time)>;
using SupportedFormatsCallback =
std::function<void(const audio_fidl::SupportedFormats& supported_formats)>;
zx_status_t Open();
zx_status_t GetSupportedFormats(const SupportedFormatsCallback& cb) const;
zx_status_t SetMute(bool mute);
zx_status_t SetAgc(bool enabled);
zx_status_t SetGain(float gain);
zx_status_t WatchGain(audio_stream_cmd_get_gain_resp_t* out_gain) const;
zx_status_t GetUniqueId(audio_stream_cmd_get_unique_id_resp_t* out_id) const;
zx_status_t GetString(audio_stream_string_id_t id,
audio_stream_cmd_get_string_resp_t* out_str) const;
zx_status_t PlugMonitor(float duration, PlugMonitorCallback* monitor);
zx_status_t SetFormat(uint32_t frames_per_second, uint16_t channels,
uint64_t channels_to_use_bitmask, audio_sample_format_t sample_format);
zx_status_t GetBuffer(uint32_t frames, uint32_t irqs_per_ring);
zx_status_t StartRingBuffer();
zx_status_t StopRingBuffer();
void ResetRingBuffer();
void Close();
zx_status_t WatchPlugState(audio_stream_cmd_plug_detect_resp_t* out_state) const;
bool IsStreamBufChannelConnected() const { return IsChannelConnected(stream_ch_); }
bool IsRingBufChannelConnected() const { return IsChannelConnected(rb_ch_); }
// Available for unit tests.
void SetStreamChannel(zx::channel channel) { stream_ch_ = std::move(channel); }
const char* name() const { return name_; }
bool input() const { return direction_ == StreamDirection::kInput; }
uint32_t frame_rate() const { return frame_rate_; }
uint32_t sample_size() const { return sample_size_; }
uint32_t channel_cnt() const { return channel_cnt_; }
uint32_t frame_sz() const { return frame_sz_; }
uint32_t fifo_depth() const { return fifo_depth_; }
uint32_t ring_buffer_bytes() const { return rb_sz_; }
void* ring_buffer() const { return rb_virt_; }
int64_t start_time() const { return start_time_; }
int64_t external_delay_nsec() const { return external_delay_nsec_; }
protected:
friend class std::default_delete<AudioDeviceStream>;
static bool IsChannelConnected(const zx::channel& ch);
AudioDeviceStream(StreamDirection direction, uint32_t dev_id);
AudioDeviceStream(StreamDirection direction, const char* dev_path);
virtual ~AudioDeviceStream();
zx::channel stream_ch_;
zx::channel rb_ch_;
zx::vmo rb_vmo_;
const StreamDirection direction_;
char name_[64] = {0};
audio_sample_format_t sample_format_;
int64_t start_time_ = 0;
int64_t external_delay_nsec_ = 0;
uint32_t frame_rate_ = 0;
uint8_t sample_size_ = 0;
uint8_t channel_size_ = 0;
uint32_t channel_cnt_ = 0;
uint32_t frame_sz_ = 0;
uint32_t fifo_depth_ = 0;
uint32_t rb_sz_ = 0;
void* rb_virt_ = nullptr;
bool muted_ = false;
bool agc_enabled_ = false;
float gain_ = 0.f;
private:
zx_status_t SetGainParams();
};
} // namespace utils
} // namespace audio
#endif // AUDIO_UTILS_AUDIO_DEVICE_STREAM_H_