dxd - dynax driver framework 3.0.2
cross platform open source driver development framework
Loading...
Searching...
No Matches
dx::usb::stream::pipe< device_t, circular_t, stream_t > Class Template Reference

one isochronous endpoint as a stream: the ring, the cycle of slots the session rotates through and the thread that ticks them. The data path itself is dx::usb::isoc::pipeline, shared with the kernel driver; this class supplies its platform part - a slot's request over its buffer, the completions in submission order, the direction's data event and the timestamp clock. An asynchronous sink keeps its sync endpoint's requests here too (isoc.sync), an implicit feedback source reads its rate off its own delivered lines. More...

#include <dx_usb_stream_pipe.h>

Inheritance diagram for dx::usb::stream::pipe< device_t, circular_t, stream_t >:
Collaboration diagram for dx::usb::stream::pipe< device_t, circular_t, stream_t >:

Classes

struct  cache
 what the tick reads instead of asking a promoted: the derived transaction sizes, the encoder stages and the in slot's sentinel - none of them may block or lock More...
struct  isoc
 what this pipe's session needs beside its own requests: the feedback ring of lines per frame, and an explicit feedback endpoint's own slots More...

Public Types

typedef struct device_t::desc::stream desc
typedef device<> device_t
typedef device<> device_t
typedef event<user> event_t
enum  type

Public Member Functions

pipe& abort()
stream& attach(void **[2], const std::vector<bool> &, direction::direction, const dx::stream::format &)
 the pin passes its own direction: a stream shared by two pins carries none of its own
 catch(const std::out_of_range& exception)
os_result charge() noexcept
 streaming session prologue: selects the alternate setting, (re-)creates the isoc buffer, then the pipeline's own - run by the thread owning the session (group pipes: the group's thread), whose ticks then submit; logs a failure as it starts and its recovery once
bool claim(direction::direction direction)
 taken while there is none
pipe& clear(bool force= false)
void conclude() noexcept override
 conclude notification: object will be removed. If you overwrite conclude() you also need to overwrite destructor and check if its needed to be called from there. Called only through try_conclude() - never call this directly from outside the class hierarchy.
pipe& drain(std::chrono::milliseconds timeout= std::chrono::milliseconds(250)) noexcept
 waits for already-submitted requests to complete on their own, without cancelling them
float encoder(dx::stream::encoder::index::type typetype, unsigned int index) const override
bool encoder(dx::stream::encoder::index::type typetype, unsigned int index, float value) override
void exception(const class exception& exception, bool filtered= false) const noexcept override
void exception(const dx::exception& exception, bool filtered= false) const noexcept override
 notification exception handler
void flush()
uint64_t frame(int64_t* timestamp= nullptr)
 current bus frame number; timestamp: dx::timestamp() of the readout
void free() noexcept override
 overrides may release further alloc()-acquired resources (request buffers, isoc pools, shared-memory attachments) alongside circular; called only from alloc()'s own self-cleanup or the destructor - never from halt()/stop(), so everything alloc() acquires stays live for the object's full lifetime
void initialize() override
void launch() override
pipe& max_frame_size(uint32_t frame_size)
 operator dx::circular*() const noexcept
dx::circular* operator ->() const noexcept
pipe& operator <<(const data_t& data)
 synchronous USB write request
pipe& operator >>(data_t& data)
 synchronous USB read request
bool outstanding() const noexcept
 pipe(device_t& device, const decltype(super::id)& id, const super::desc& descdesc)
 creates this->circular streaming backing store and frame buffers
bool poll(usb::isoc::result& result) noexcept
 pulls the oldest completed request's result
pipe& read(void* data, size_t& size)
 synchronous USB read request
virtual pipe& receive(void* data, size_t size)
 asynchronous USB read request
virtual os_result status() noexcept
os_result status() const noexcept
virtual bool submit(dx::stream::encoder::index::type, unsigned int, uint8_t)
 submit encoder stage to device return true if successfully submitted; if false is returned the encode state machine will not update the stage value (i.e. if the stage can't be submitted during streaming pause), given the chance to submit the stage at start().
pipe& submit(const request<data_t>& request) const
 standard request to pipe
pipe& transfer(bool in, void* data, size_t& size)
 a synchronous transfer: asynchronous underneath, past timeout the pipe aborted and the transfer failed as timed out - IOKit completes every request, an aborted one included
virtual pipe& transmit(const void* data, size_t& size)
 asynchronous USB write request
bool try_conclude() noexcept
 atomically conclude()s if currently launched; returns whether this call did it
bool try_conclude() noexcept
 atomically conclude()s if currently launched; returns whether this call did it
bool try_launch()
 atomically launch()es if not already launched; returns whether this call did it. A launch() that throws is concluded before the exception leaves: the object never claims a launch it did not finish
bool try_launch()
 atomically launch()es if not already launched; returns whether this call did it. A launch() that throws is concluded before the exception leaves: the object never claims a launch it did not finish
pipe& write(const void* data, size_t size)
 synchronous USB write request
 ~pipe() override

Static Public Member Functions

static unsigned int micro_frames(const device_t& device, uint8_t bInterval)
 an endpoint's requests per frame: its interval at high speed, one below

Public Attributes

bool anchored
 origin is set: by the tick that first finds the ring ticking, reset by the run hook
const usb::endpoint::attributes& attributes
std::deque<union audio::descriptor::endpoint> audio
uint8_t bRefresh
 audio class endpoint: 2^bRefresh frames between two feedback values
uint8_t bSynchAddress
 audio class endpoint: the isoc sync endpoint pacing this one, 0: none
dx::stream::channel::control* control
 kernel streaming: the driver's buffer switch bookkeeping, set by attach()
event_t data [direction::directions]
 event signalising data arrival(in) or draining(out)
dx::promoted<dx::stream::format> format
 the container this stream's ring runs: class and width its participants agreed on
const decltype(desc::target.idx()) id
interface& interface
uint32_t latency
std::atomic<bool> launched
std::atomic<bool> launched
int64_t origin
 the ring's index at the device's sample zero: a ticking group keeps every ring's cycle from its device time and this
decltype(device_t::samplerate)& samplerate
promoted<uint32_t> start
promoted<uint32_t> start
promoted<bool> started
promoted<bool> started
bool ticking
 the tick's own view of this stream's session: set by the run hook once the ring stands, cleared by the halt hook before the session ends - a plain flag, the tick must never block on a promoted's transition
std::chrono::milliseconds timeout
volatile int64_t transport
std::mutex writer
 the ring's client writers one at a time: a stream's pins write one ring, each on its own port

Static Public Attributes

static constexpr auto max

Protected Member Functions

void alloc(size_t= 0, bool free= true) override
void isoc_buffer_create()
 (re-)creates the buffered isoc pipe's tick-staging buffer via isoc.buffer.create(); safe to call again per start/stop cycle since cache.buffered keeps this->circular on its own, separate, construction-time allocation (super::alloc() below).
void pump_in() noexcept
 data driven streaming in
void pump_out() noexcept
 data driven streaming out
void received(os_result status, size_t size) override
 async read callback
void transmitted(os_result status, size_t size) override
 async write callback
virtual size_t vendor(uint8_t *, size_t size, bool)
 a vendor transaction's wire bytes past its fill (out; data false: an idle transaction) and ahead of its take (in): returns the bytes the ring takes

Protected Attributes

struct dx::usb::platform::pipe:: { ... }  address
struct dx::usb::stream::pipe:: { ... }  async
struct dx::usb::stream::pipe::cache cache
listener<dx::listen<std::function<void(const uint32_t &)>>> cadence_listener{this->samplerate.listen, {[this](const uint32_t& samplerate){pipeline.rate(samplerate);}}}
 the tick reads the cache, never the promoted: the rate's derivations are the pipeline's, rederived on every commit
dx::circular* circular
 allocated once by initialize()/alloc(); released only by free()
usb::isoc::result completed [max]
 isoc completions in callback order, filled by the runloop, drained by poll()
device<>& device
device<>& device
std::function<void()> flush_hook
std::function<void()> flush_hook
std::function<void()> halt_hook
std::function<void()> halt_hook
uint8_t idx
struct dx::usb::stream::pipe::isoc isoc
listener<dx::listen<std::function<void(const uint32_t &)>>> lead_listener{this->device[*this].transport::safety_offset[this->target.direction].listen, {[this](const uint32_t& ticks){pipeline.cache.lead= ticks;}}}
 a lead set mid-session moves the tick's slots along
std::function<void()> run_hook
std::function<void()> run_hook
volatile unsigned int rx
struct dx::usb::stream::pipe:: { ... }  sync
volatile unsigned int tx
struct dx::usb::platform::pipe:: { ... }  winusb

Friends

class isoc::pipeline<pipe, circular_t>
struct isoc::session<usb::stream::group<device_t>>
class pause
class usb::stream::group<device_t>

Detailed Description

template<typename device_t, typename circular_t = dx::circular, template< typename ... > typename stream_t = dx::stream::stream>
class dx::usb::stream::pipe< device_t, circular_t, stream_t >

one isochronous endpoint as a stream: the ring, the cycle of slots the session rotates through and the thread that ticks them. The data path itself is dx::usb::isoc::pipeline, shared with the kernel driver; this class supplies its platform part - a slot's request over its buffer, the completions in submission order, the direction's data event and the timestamp clock. An asynchronous sink keeps its sync endpoint's requests here too (isoc.sync), an implicit feedback source reads its rate off its own delivered lines.

Member Typedef Documentation

◆ desc

typedef struct device_t::desc::stream dx::stream::stream<device_t, dx::circular, usb::pipe<device_t>, event<user>>::desc
inherited

◆ device_t [1/2]

typedef device<> dx::stream::object<device<>>::device_t
inherited

◆ device_t [2/2]

typedef device<> dx::stream::object<device<>>::device_t
inherited

◆ event_t

Member Enumeration Documentation

◆ type

Constructor & Destructor Documentation

◆ pipe()

template<typename device_t, typename circular_t= dx::circular, template<typename ...> typename stream_t= dx::stream::stream>
dx::usb::stream::pipe<device_t, circular_t, stream_t>::pipe(device_t& device, const decltype(super::id)& id, const super::desc& desc)
inline

creates this->circular streaming backing store and frame buffers

stream::stream's ring reset, composed with usb::platform::pipe's completion-thread launch

stream::stream's group decrement, composed with usb::platform::pipe's join-outstanding-requests wait

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ~pipe()

template<typename device_t, typename circular_t= dx::circular, template<typename ...> typename stream_t= dx::stream::stream>
dx::usb::stream::pipe<device_t, circular_t, stream_t>::~pipe()
inlineoverride
Here is the call graph for this function:

Member Function Documentation

◆ abort()

pipe& dx::usb::platform::pipe<device<>, interface>::abort()
inlineinherited
Here is the caller graph for this function:

◆ alloc()

template<typename device_t, typename circular_t= dx::circular, template<typename ...> typename stream_t= dx::stream::stream>
void dx::usb::stream::pipe<device_t, circular_t, stream_t>::alloc(size_t= 0, bool free= true)
inlineoverrideprotectedvirtual

generates isoc cycle metrics from sample rate,

requests buffers to fit at least 3x max iosize with isoc cycle size granularity

update max frame size

Todo
reset max frame size when pipe is closed

Reimplemented from dx::stream::stream< device_t, dx::circular, usb::pipe< device_t > >.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ attach()

the pin passes its own direction: a stream shared by two pins carries none of its own

◆ catch()

dx::usb::pipe<device_t>::catch(const std::out_of_range& exception)
inlineinherited

◆ charge()

template<typename device_t, typename circular_t= dx::circular, template<typename ...> typename stream_t= dx::stream::stream>
os_result dx::usb::stream::pipe<device_t, circular_t, stream_t>::charge()
inlinenoexcept

streaming session prologue: selects the alternate setting, (re-)creates the isoc buffer, then the pipeline's own - run by the thread owning the session (group pipes: the group's thread), whose ticks then submit; logs a failure as it starts and its recovery once

Here is the call graph for this function:
Here is the caller graph for this function:

◆ claim()

taken while there is none

◆ clear()

pipe& dx::usb::platform::pipe<device<>, interface>::clear(bool force= false)
inlineinherited
Here is the caller graph for this function:

◆ conclude()

void dx::usb::pipe<device_t>::conclude()
inlineoverridevirtualnoexceptinherited

conclude notification: object will be removed. If you overwrite conclude() you also need to overwrite destructor and check if its needed to be called from there. Called only through try_conclude() - never call this directly from outside the class hierarchy.

Reimplemented from dx::stream::control< stream::object< device_t > >.

Here is the caller graph for this function:

◆ drain()

pipe& dx::usb::platform::pipe<device<>, interface>::drain(std::chrono::milliseconds timeout= std::chrono::milliseconds(250))
inlinenoexceptinherited

waits for already-submitted requests to complete on their own, without cancelling them

Here is the caller graph for this function:

◆ encoder() [1/2]

template<typename device_t, typename circular_t= dx::circular, template<typename ...> typename stream_t= dx::stream::stream>
float dx::usb::stream::pipe<device_t, circular_t, stream_t>::encoder(dx::stream::encoder::index::type type, unsigned int index) const
inlineoverride
Here is the call graph for this function:

◆ encoder() [2/2]

template<typename device_t, typename circular_t= dx::circular, template<typename ...> typename stream_t= dx::stream::stream>
bool dx::usb::stream::pipe<device_t, circular_t, stream_t>::encoder(dx::stream::encoder::index::type type, unsigned int index, float value)
inlineoverridevirtual

Reimplemented from dx::stream::stream< device_t, dx::circular, usb::pipe< device_t > >.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ exception() [1/2]

void dx::stream::stream<device_t, dx::circular, usb::pipe<device_t>, event<user>>::exception(const class exception& exception, bool filtered= false) const
inlineoverridenoexceptinherited

◆ exception() [2/2]

template<typename device_t, typename circular_t= dx::circular, template<typename ...> typename stream_t= dx::stream::stream>
void dx::usb::stream::pipe<device_t, circular_t, stream_t>::exception(const dx::exception& exception, bool filtered= false) const
inlineoverridevirtualnoexcept

notification exception handler

Reimplemented from dx::stream::object< _device_t >.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ flush()

void dx::stream::stream<device_t, dx::circular, usb::pipe<device_t>, event<user>>::flush()
inlineinherited

◆ frame()

uint64_t dx::usb::platform::pipe<device<>, interface>::frame(int64_t* timestamp= nullptr)
inlineinherited

current bus frame number; timestamp: dx::timestamp() of the readout

◆ free()

template<typename device_t, typename circular_t= dx::circular, template<typename ...> typename stream_t= dx::stream::stream>
void dx::usb::stream::pipe<device_t, circular_t, stream_t>::free()
inlineoverridevirtualnoexcept

overrides may release further alloc()-acquired resources (request buffers, isoc pools, shared-memory attachments) alongside circular; called only from alloc()'s own self-cleanup or the destructor - never from halt()/stop(), so everything alloc() acquires stays live for the object's full lifetime

Reimplemented from dx::stream::stream< device_t, dx::circular, usb::pipe< device_t > >.

Here is the caller graph for this function:

◆ initialize()

template<typename device_t, typename circular_t= dx::circular, template<typename ...> typename stream_t= dx::stream::stream>
void dx::usb::stream::pipe<device_t, circular_t, stream_t>::initialize()
inlineoverridevirtual

Reimplemented from dx::stream::stream< device_t, dx::circular, usb::pipe< device_t > >.

Here is the call graph for this function:

◆ isoc_buffer_create()

template<typename device_t, typename circular_t= dx::circular, template<typename ...> typename stream_t= dx::stream::stream>
void dx::usb::stream::pipe<device_t, circular_t, stream_t>::isoc_buffer_create()
inlineprotected

(re-)creates the buffered isoc pipe's tick-staging buffer via isoc.buffer.create(); safe to call again per start/stop cycle since cache.buffered keeps this->circular on its own, separate, construction-time allocation (super::alloc() below).

Todo
dx::usb::stream::pipe: the non-buffered isoc case (see alloc() below) still only creates once, at construction, since c77a0974's this->circular null-pointer fix depends on that staying true; unexercised by any currently shipping device
Here is the caller graph for this function:

◆ launch()

void dx::stream::stream<device_t, dx::circular, usb::pipe<device_t>, event<user>>::launch()
inlineoverridevirtualinherited

Reimplemented from dx::object.

◆ max_frame_size()

pipe& dx::usb::pipe<device_t>::max_frame_size(uint32_t frame_size)
inlineinherited
Here is the caller graph for this function:

◆ micro_frames()

unsigned int dx::usb::pipe<device_t>::micro_frames(const device_t& device, uint8_t bInterval)
inlinestaticinherited

an endpoint's requests per frame: its interval at high speed, one below

Here is the caller graph for this function:

◆ operator dx::circular *()

dx::stream::stream<device_t, dx::circular, usb::pipe<device_t>, event<user>>::operator dx::circular*() const
inlinenoexceptinherited

◆ operator ->()

dx::circular* dx::stream::stream<device_t, dx::circular, usb::pipe<device_t>, event<user>>::operator ->() const
inlinenoexceptinherited

◆ operator <<()

pipe& dx::usb::pipe<device_t>::operator <<(const data_t& data)
inlineinherited

synchronous USB write request

◆ operator >>()

pipe& dx::usb::pipe<device_t>::operator >>(data_t& data)
inlineinherited

synchronous USB read request

◆ outstanding()

bool dx::usb::platform::pipe<device<>, interface>::outstanding() const
inlinenoexceptinherited

asynchronous requests in flight

Here is the caller graph for this function:

◆ poll()

bool dx::usb::platform::pipe<device<>, interface>::poll(usb::isoc::result& result)
inlinenoexceptinherited

pulls the oldest completed request's result

◆ pump_in()

template<typename device_t, typename circular_t= dx::circular, template<typename ...> typename stream_t= dx::stream::stream>
void dx::usb::stream::pipe<device_t, circular_t, stream_t>::pump_in()
inlineprotectednoexcept

data driven streaming in

postponed

Here is the call graph for this function:
Here is the caller graph for this function:

◆ pump_out()

template<typename device_t, typename circular_t= dx::circular, template<typename ...> typename stream_t= dx::stream::stream>
void dx::usb::stream::pipe<device_t, circular_t, stream_t>::pump_out()
inlineprotectednoexcept

data driven streaming out

Here is the call graph for this function:
Here is the caller graph for this function:

◆ read()

pipe& dx::usb::platform::pipe<device<>, interface>::read(void* data, size_t& size)
inlineinherited

synchronous USB read request

◆ receive()

virtual pipe& dx::usb::platform::pipe<device<>, interface>::receive(void* data, size_t size)
inlinevirtualinherited

asynchronous USB read request

◆ received()

template<typename device_t, typename circular_t= dx::circular, template<typename ...> typename stream_t= dx::stream::stream>
void dx::usb::stream::pipe<device_t, circular_t, stream_t>::received(os_result status, size_t size)
inlineoverrideprotectedvirtual

async read callback

Todo
evaluate non-transaction size transmit handling
Todo
log async write callback

generates timestamp

Reimplemented from dx::usb::platform::pipe< device_t, interface >.

Here is the call graph for this function:

◆ status() [1/2]

virtual os_result dx::stream::stream<device_t, dx::circular, usb::pipe<device_t>, event<user>>::status()
inlinevirtualnoexceptinherited
Here is the caller graph for this function:

◆ status() [2/2]

os_result dx::usb::platform::pipe<device<>, interface>::status() const
inlinenoexceptinherited

◆ submit() [1/2]

submit encoder stage to device return true if successfully submitted; if false is returned the encode state machine will not update the stage value (i.e. if the stage can't be submitted during streaming pause), given the chance to submit the stage at start().

Here is the caller graph for this function:

◆ submit() [2/2]

pipe& dx::usb::platform::pipe<device<>, interface>::submit(const request<data_t>& request) const
inlineinherited

standard request to pipe

◆ transfer()

pipe& dx::usb::platform::pipe<device<>, interface>::transfer(bool in, void* data, size_t& size)
inlineinherited

a synchronous transfer: asynchronous underneath, past timeout the pipe aborted and the transfer failed as timed out - IOKit completes every request, an aborted one included

◆ transmit()

virtual pipe& dx::usb::platform::pipe<device<>, interface>::transmit(const void* data, size_t& size)
inlinevirtualinherited

asynchronous USB write request

◆ transmitted()

template<typename device_t, typename circular_t= dx::circular, template<typename ...> typename stream_t= dx::stream::stream>
void dx::usb::stream::pipe<device_t, circular_t, stream_t>::transmitted(os_result status, size_t size)
inlineoverrideprotectedvirtual

async write callback

Todo
evaluate non-transaction size transmit handling
Todo
log async write callback
Todo
evaluate transaction size vs. ring buffer read size
Todo
USB HW clock support: hardcoded to USB/out - needs to be handled by clock class

generates timestamp

Reimplemented from dx::usb::platform::pipe< device_t, interface >.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_conclude() [1/2]

bool dx::object::try_conclude()
inlinenoexceptinherited

atomically conclude()s if currently launched; returns whether this call did it

◆ try_conclude() [2/2]

bool dx::object::try_conclude()
inlinenoexceptinherited

atomically conclude()s if currently launched; returns whether this call did it

◆ try_launch() [1/2]

bool dx::object::try_launch()
inlineinherited

atomically launch()es if not already launched; returns whether this call did it. A launch() that throws is concluded before the exception leaves: the object never claims a launch it did not finish

◆ try_launch() [2/2]

bool dx::object::try_launch()
inlineinherited

atomically launch()es if not already launched; returns whether this call did it. A launch() that throws is concluded before the exception leaves: the object never claims a launch it did not finish

◆ vendor()

template<typename device_t, typename circular_t= dx::circular, template<typename ...> typename stream_t= dx::stream::stream>
virtual size_t dx::usb::stream::pipe<device_t, circular_t, stream_t>::vendor(uint8_t*, size_t size, bool)
inlineprotectedvirtual

a vendor transaction's wire bytes past its fill (out; data false: an idle transaction) and ahead of its take (in): returns the bytes the ring takes

Here is the caller graph for this function:

◆ write()

pipe& dx::usb::platform::pipe<device<>, interface>::write(const void* data, size_t size)
inlineinherited

synchronous USB write request

Here is the caller graph for this function:

◆ isoc::pipeline<pipe, circular_t>

template<typename device_t, typename circular_t= dx::circular, template<typename ...> typename stream_t= dx::stream::stream>
friend class isoc::pipeline<pipe, circular_t>
friend

◆ isoc::session<usb::stream::group<device_t>>

template<typename device_t, typename circular_t= dx::circular, template<typename ...> typename stream_t= dx::stream::stream>
friend struct isoc::session<usb::stream::group<device_t>>
friend

◆ pause

template<typename device_t, typename circular_t= dx::circular, template<typename ...> typename stream_t= dx::stream::stream>
friend class pause
friend

◆ usb::stream::group<device_t>

template<typename device_t, typename circular_t= dx::circular, template<typename ...> typename stream_t= dx::stream::stream>
friend class usb::stream::group<device_t>
friend

Member Data Documentation

◆ address

struct { ... } dx::usb::platform::pipe<device<>, interface>::address

◆ anchored

origin is set: by the tick that first finds the ring ticking, reset by the run hook

◆ async

struct { ... } dx::usb::stream::pipe<device_t, circular_t, stream_t>::async

◆ attributes

const usb::endpoint::attributes& dx::usb::pipe<device_t>::attributes
inherited

◆ audio

◆ bRefresh

audio class endpoint: 2^bRefresh frames between two feedback values

◆ bSynchAddress

audio class endpoint: the isoc sync endpoint pacing this one, 0: none

◆ cache

template<typename device_t, typename circular_t= dx::circular, template<typename ...> typename stream_t= dx::stream::stream>
struct dx::usb::stream::pipe::cache dx::usb::stream::pipe<device_t, circular_t, stream_t>::cache
protected

◆ cadence_listener

template<typename device_t, typename circular_t= dx::circular, template<typename ...> typename stream_t= dx::stream::stream>
listener<dx::listen<std::function<void(const uint32_t&)>>> dx::usb::stream::pipe<device_t, circular_t, stream_t>::cadence_listener{this->samplerate.listen,{[this](const uint32_t& samplerate){pipeline.rate(samplerate);}}}
protected

the tick reads the cache, never the promoted: the rate's derivations are the pipeline's, rederived on every commit

◆ circular

allocated once by initialize()/alloc(); released only by free()

◆ completed

usb::isoc::result dx::usb::platform::pipe<device<>, interface>::completed[max]
protectedinherited

isoc completions in callback order, filled by the runloop, drained by poll()

◆ control

kernel streaming: the driver's buffer switch bookkeeping, set by attach()

◆ data

event_t dx::stream::stream<device_t, dx::circular, usb::pipe<device_t>, event<user>>::data[direction::directions]
inherited

event signalising data arrival(in) or draining(out)

◆ device [1/2]

device<>& dx::stream::object<device<>>::device
protectedinherited

◆ device [2/2]

device<>& dx::stream::object<device<>>::device
protectedinherited

◆ flush_hook [1/2]

std::function<void()> dx::stream::control<stream::object<device<>>>::flush_hook
protectedinherited

◆ flush_hook [2/2]

std::function<void()> dx::stream::control<dx::stream::object<device<>>>::flush_hook
protectedinherited

◆ format

the container this stream's ring runs: class and width its participants agreed on

A bus that negotiates it installs its own server; without one the request stands, unless the stream's configuration states its format: that one runs whatever is asked. The seed is the desc's own pin format, so a stream that nobody contradicts runs what it was declared with.

◆ halt_hook [1/2]

std::function<void()> dx::stream::control<stream::object<device<>>>::halt_hook
protectedinherited

◆ halt_hook [2/2]

std::function<void()> dx::stream::control<dx::stream::object<device<>>>::halt_hook
protectedinherited

◆ id

const decltype(desc::target.idx()) dx::stream::stream<device_t, dx::circular, usb::pipe<device_t>, event<user>>::id
inherited

◆ idx

uint8_t dx::usb::platform::pipe<device<>, interface>::idx
protectedinherited

◆ interface

interface & dx::usb::platform::pipe<device<>, interface>::interface
inherited

◆ isoc

template<typename device_t, typename circular_t= dx::circular, template<typename ...> typename stream_t= dx::stream::stream>
struct dx::usb::stream::pipe::isoc dx::usb::stream::pipe<device_t, circular_t, stream_t>::isoc
protected

◆ latency

◆ launched [1/2]

std::atomic<bool> dx::object::launched
inherited

◆ launched [2/2]

std::atomic<bool> dx::object::launched
inherited

◆ lead_listener

template<typename device_t, typename circular_t= dx::circular, template<typename ...> typename stream_t= dx::stream::stream>
listener<dx::listen<std::function<void(const uint32_t&)>>> dx::usb::stream::pipe<device_t, circular_t, stream_t>::lead_listener{this->device[*this].transport::safety_offset[this->target.direction].listen,{[this](const uint32_t& ticks){pipeline.cache.lead= ticks;}}}
protected

a lead set mid-session moves the tick's slots along

◆ max

constexpr auto dx::usb::platform::pipe<device<>, interface>::max
staticconstexprinherited

◆ origin

the ring's index at the device's sample zero: a ticking group keeps every ring's cycle from its device time and this

◆ run_hook [1/2]

std::function<void()> dx::stream::control<stream::object<device<>>>::run_hook
protectedinherited

◆ run_hook [2/2]

std::function<void()> dx::stream::control<dx::stream::object<device<>>>::run_hook
protectedinherited

◆ rx

volatile unsigned int dx::usb::platform::pipe<device<>, interface>::rx
protectedinherited

◆ samplerate

decltype(device_t::samplerate) & dx::stream::stream<device_t, dx::circular, usb::pipe<device_t>, event<user>>::samplerate
inherited

◆ start [1/2]

◆ start [2/2]

◆ started [1/2]

promoted<bool> dx::stream::control<stream::object<device<>>>::started
inherited

◆ started [2/2]

promoted<bool> dx::stream::control<dx::stream::object<device<>>>::started
inherited

◆ sync

struct { ... } dx::usb::stream::pipe<device_t, circular_t, stream_t>::sync

◆ ticking

the tick's own view of this stream's session: set by the run hook once the ring stands, cleared by the halt hook before the session ends - a plain flag, the tick must never block on a promoted's transition

◆ timeout

std::chrono::milliseconds dx::usb::platform::pipe<device<>, interface>::timeout
inherited

a synchronous transfer's bound, 0: none

◆ transport

the ring's one transport while a participant holds it, of the direction the desc declares: none again at its release and at the session's halt

◆ tx

volatile unsigned int dx::usb::platform::pipe<device<>, interface>::tx
protectedinherited

◆ winusb

struct { ... } dx::usb::platform::pipe<device<>, interface>::winusb

◆ writer

std::mutex dx::stream::stream<device_t, dx::circular, usb::pipe<device_t>, event<user>>::writer
inherited

the ring's client writers one at a time: a stream's pins write one ring, each on its own port


The documentation for this class was generated from the following file: