blob: 30b36ceab29cd838203418ec17628f013e28b7e5 [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 GARNET_DRIVERS_AUDIO_VIRTUAL_AUDIO_VIRTUAL_AUDIO_STREAM_H_
#define GARNET_DRIVERS_AUDIO_VIRTUAL_AUDIO_VIRTUAL_AUDIO_STREAM_H_
#include <audio-proto/audio-proto.h>
#include <dispatcher-pool/dispatcher-timer.h>
#include <dispatcher-pool/dispatcher-wakeup-event.h>
#include <fbl/ref_ptr.h>
#include <fuchsia/virtualaudio/cpp/fidl.h>
#include <lib/fzl/vmo-mapper.h>
#include <lib/simple-audio-stream/simple-audio-stream.h>
#include <deque>
namespace virtual_audio {
class VirtualAudioDeviceImpl;
class VirtualAudioStream : public ::audio::SimpleAudioStream {
public:
void EnqueuePlugChange(bool plugged) __TA_EXCLUDES(wakeup_queue_lock_);
static fbl::RefPtr<VirtualAudioStream> CreateStream(
VirtualAudioDeviceImpl* owner, zx_device_t* devnode, bool is_input);
// Only set by DeviceImpl -- on dtor, Disable or Remove
bool shutdown_by_parent_ = false;
protected:
friend class ::audio::SimpleAudioStream;
friend class fbl::RefPtr<VirtualAudioStream>;
VirtualAudioStream(VirtualAudioDeviceImpl* parent, zx_device_t* dev_node,
bool is_input)
: ::audio::SimpleAudioStream(dev_node, is_input), parent_(parent) {}
~VirtualAudioStream() override;
zx_status_t Init() __TA_REQUIRES(domain_->token()) override;
zx_status_t InitPost() override;
zx_status_t ChangeFormat(const ::audio::audio_proto::StreamSetFmtReq& req)
__TA_REQUIRES(domain_->token()) override;
zx_status_t SetGain(const ::audio::audio_proto::SetGainReq& req)
__TA_REQUIRES(domain_->token()) override;
zx_status_t GetBuffer(const ::audio::audio_proto::RingBufGetBufferReq& req,
uint32_t* out_num_rb_frames, zx::vmo* out_buffer)
__TA_REQUIRES(domain_->token()) override;
zx_status_t Start(uint64_t* out_start_time)
__TA_REQUIRES(domain_->token()) override;
zx_status_t Stop() __TA_REQUIRES(domain_->token()) override;
void ShutdownHook() __TA_REQUIRES(domain_->token()) override;
// RingBufferShutdown() is unneeded: no hardware shutdown tasks needed...
zx_status_t ProcessRingNotification() __TA_REQUIRES(domain_->token());
enum class PlugType { Plug, Unplug };
void HandlePlugChanges() __TA_REQUIRES(domain_->token())
__TA_EXCLUDES(wakeup_queue_lock_);
void HandlePlugChange(PlugType plug_change) __TA_REQUIRES(domain_->token());
// Accessed in GetBuffer, defended by token.
fzl::VmoMapper ring_buffer_mapper_ __TA_GUARDED(domain_->token());
zx::vmo ring_buffer_vmo_ __TA_GUARDED(domain_->token());
uint32_t num_ring_buffer_frames_ __TA_GUARDED(domain_->token()) = 0;
uint32_t max_buffer_frames_ __TA_GUARDED(domain_->token());
uint32_t min_buffer_frames_ __TA_GUARDED(domain_->token());
uint32_t modulo_buffer_frames_ __TA_GUARDED(domain_->token());
fbl::RefPtr<dispatcher::Timer> notify_timer_;
uint32_t us_per_notification_ __TA_GUARDED(domain_->token()) = 0;
uint32_t notifications_per_ring_ __TA_GUARDED(domain_->token()) = 0;
zx::time start_time_ __TA_GUARDED(domain_->token());
uint32_t bytes_per_sec_ __TA_GUARDED(domain_->token()) = 0;
uint32_t frame_rate_ __TA_GUARDED(domain_->token()) = 0;
audio_sample_format_t sample_format_ __TA_GUARDED(domain_->token()) = 0;
uint32_t num_channels_ __TA_GUARDED(domain_->token()) = 0;
VirtualAudioDeviceImpl* parent_ __TA_GUARDED(domain_->token());
fbl::Mutex wakeup_queue_lock_ __TA_ACQUIRED_AFTER(domain_->token());
fbl::RefPtr<::dispatcher::WakeupEvent> plug_change_wakeup_;
std::deque<PlugType> plug_queue_ __TA_GUARDED(wakeup_queue_lock_);
};
} // namespace virtual_audio
#endif // GARNET_DRIVERS_AUDIO_VIRTUAL_AUDIO_VIRTUAL_AUDIO_STREAM_H_