dxd - dynax driver framework 3.0.0d222
cross platform open source driver development framework
Loading...
Searching...
No Matches
dx::coremidi::stream< device_t, circular_t > Class Template Reference

#include <dx_coremidi_device.h>

Inheritance diagram for dx::coremidi::stream< device_t, circular_t >:
Collaboration diagram for dx::coremidi::stream< device_t, circular_t >:

Public Types

typedef struct device_t::desc::stream desc
typedef event< userevent_t

Public Member Functions

streamattach (channel_t **[2], const std::vector< bool > &, direction::direction)
 the pin passes its own direction: a stream shared by two pins carries none of its own
virtual bool encoder (dx::stream::encoder::index::type, unsigned int, float)
void exception (const class exception &exception, bool filtered=false) const noexcept override
void flush ()
void info (std::ostream &os) noexcept override
virtual void initialize ()
void launch () override
uint64_t lost () const noexcept
 the words CoreMIDI had no room for in the ring
 operator dx::midi::ump::circular * () const noexcept
dx::midi::ump::circularoperator-> () const noexcept
void receive (const ::MIDIEventList &list) noexcept
 receive Universal MIDI Packets from the system
 stream (device_t &device, const decltype(super::id)&id, const super::desc &desc)
 creates CoreMIDI endpoint connection and attaches stream to it
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().
 ~stream () override

Public Attributes

struct { 
   uint32_t   granularity 
   uint32_t   linesize 
   dx::stream::clock::monitor *   monitor 
   os_result   status 
cache
dx::stream::channel::controlcontrol
 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::formatformat
 the container this stream's ring runs: class and width its participants agreed on
uint32_t granularity
const decltype(desc::target.idx()) id
uint32_t latency
uint32_t linesize
dx::stream::clock::monitormonitor
decltype(device_t::samplerate) & samplerate
os_result status
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

Protected Member Functions

virtual void alloc (size_t size, bool free=true)
void deposit (int64_t timestamp, const uint32_t *words, uint32_t count) noexcept
 a run of words into the ring, stamped at the moment they arrived: dropped where the ring is full, never stalling the endpoint's thread
virtual void free () noexcept
 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 send (const dx::midi::ump::packet *packet, uint64_t count)
 the packets of one run to the endpoint, every one at its own moment CoreMIDI schedules what is due later itself, so a packet keeps the frame it was written at; a list that is full goes as it stands and the packet opens the next one.
void transmit () noexcept
 circular data driven streaming out thread

Protected Attributes

dx::midi::ump::circularcircular
 allocated once by initialize()/alloc(); released only by free()
::MIDIEndpointRef endpoint {}
::MIDIPortRef port {}
::MIDIProtocolID protocol = ::kMIDIProtocol_1_0
 what the port speaks: MIDI 1.0 in Universal MIDI Packets, so a legacy endpoint is translated by CoreMIDI and a MIDI 2.0 one keeps its own words

Private Member Functions

referenceinitialize (::CFStringRef cf_object, bool retain=true)

Static Private Member Functions

::CFTypeID id () noexcept

Member Typedef Documentation

◆ desc

typedef struct device_t::desc::stream dx::stream::stream< device_t, dx::midi::ump::circular, control<object<device_t>>, event<user> >::desc
inherited

◆ event_t

typedef event<user> dx::stream::stream< device_t, dx::midi::ump::circular, control<object<device_t>>, event<user> >::event_t
inherited

Constructor & Destructor Documentation

◆ stream()

template<typename device_t, typename circular_t = dx::midi::ump::circular>
dx::coremidi::stream< device_t, circular_t >::stream ( device_t & device,
const decltype(super::id)& id,
const super::desc & desc )
inline

creates CoreMIDI endpoint connection and attaches stream to it

The port speaks Universal MIDI Packets (MIDIInputPortCreateWithProtocol, MIDISendEventList), which CoreMIDI has since macOS 11; an older system has no MIDI endpoint of this client.

the ring reset, composed with the data-driven OUT stream's own transmit thread

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

◆ ~stream()

template<typename device_t, typename circular_t = dx::midi::ump::circular>
dx::coremidi::stream< device_t, circular_t >::~stream ( )
inlineoverride
Here is the call graph for this function:

Member Function Documentation

◆ alloc()

virtual void dx::stream::stream< device_t, dx::midi::ump::circular, control<object<device_t>>, event<user> >::alloc ( size_t size,
bool free = true )
inlineprotectedvirtualinherited

◆ attach()

stream & dx::stream::stream< device_t, dx::midi::ump::circular, control<object<device_t>>, event<user> >::attach ( channel_t ** [2],
const std::vector< bool > & ,
direction::direction  )
inlineinherited

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

◆ deposit()

template<typename device_t, typename circular_t = dx::midi::ump::circular>
void dx::coremidi::stream< device_t, circular_t >::deposit ( int64_t timestamp,
const uint32_t * words,
uint32_t count )
inlineprotectednoexcept

a run of words into the ring, stamped at the moment they arrived: dropped where the ring is full, never stalling the endpoint's thread

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

◆ encoder()

virtual bool dx::stream::stream< device_t, dx::midi::ump::circular, control<object<device_t>>, event<user> >::encoder ( dx::stream< device_t, dx::midi::ump::circular >::encoder::index::type ,
unsigned int ,
float  )
inlinevirtualinherited

◆ exception()

void dx::stream::stream< device_t, dx::midi::ump::circular, control<object<device_t>>, event<user> >::exception ( const class exception & exception,
bool filtered = false ) const
inlineoverridenoexceptinherited

◆ flush()

void dx::stream::stream< device_t, dx::midi::ump::circular, control<object<device_t>>, event<user> >::flush ( )
inlineinherited

◆ free()

virtual void dx::stream::stream< device_t, dx::midi::ump::circular, control<object<device_t>>, event<user> >::free ( )
inlineprotectedvirtualnoexceptinherited

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

◆ info()

void dx::stream::stream< device_t, dx::midi::ump::circular, control<object<device_t>>, event<user> >::info ( std::ostream< device_t, dx::midi::ump::circular > & os)
inlineoverridenoexceptinherited

◆ initialize()

virtual void dx::stream::stream< device_t, dx::midi::ump::circular, control<object<device_t>>, event<user> >::initialize ( )
inlinevirtualinherited

< a shared ring takes the wider of its two directions

< this stream's own contribution: the frames its transport keeps ahead of/behind the ring

< a ring stating its size is its host's (kernel, service, plugin) and attached as it stands; a fresh one, zeroed by alloc(), takes its size here

◆ launch()

void dx::stream::stream< device_t, dx::midi::ump::circular, control<object<device_t>>, event<user> >::launch ( )
inlineoverrideinherited

◆ lost()

template<typename device_t, typename circular_t = dx::midi::ump::circular>
uint64_t dx::coremidi::stream< device_t, circular_t >::lost ( ) const
inlinenoexcept

the words CoreMIDI had no room for in the ring

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

◆ operator dx::midi::ump::circular *()

dx::stream::stream< device_t, dx::midi::ump::circular, control<object<device_t>>, event<user> >::operator dx::midi::ump::circular * ( ) const
inlinenoexceptinherited

◆ operator->()

dx::midi::ump::circular * dx::stream::stream< device_t, dx::midi::ump::circular, control<object<device_t>>, event<user> >::operator-> ( ) const
inlinenoexceptinherited

◆ receive()

template<typename device_t, typename circular_t = dx::midi::ump::circular>
void dx::coremidi::stream< device_t, circular_t >::receive ( const ::MIDIEventList & list)
inlinenoexcept

receive Universal MIDI Packets from the system

receive is seen from the based circular buffer perspective: the packets are written into the circular buffer (to be used by this client driver hosting application) at the moment CoreMIDI stamped them with - the host clock, which is dx::timestamp() itself, so nothing is converted.

flow control & signalisation this->data[dx::stream::direction::in] -> signals data arrival(in) It is the endpoint's own thread, so a full ring drops the words and counts them (lost()) rather than stalling MIDI reception.

Here is the call graph for this function:

◆ send()

template<typename device_t, typename circular_t = dx::midi::ump::circular>
void dx::coremidi::stream< device_t, circular_t >::send ( const dx::midi::ump::packet * packet,
uint64_t count )
inlineprotected

the packets of one run to the endpoint, every one at its own moment CoreMIDI schedules what is due later itself, so a packet keeps the frame it was written at; a list that is full goes as it stands and the packet opens the next one.

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

◆ submit()

virtual bool dx::stream::stream< device_t, dx::midi::ump::circular, control<object<device_t>>, event<user> >::submit ( dx::stream< device_t, dx::midi::ump::circular >::encoder::index::type ,
unsigned int ,
uint8_t  )
inlinevirtualinherited

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().

◆ transmit()

template<typename device_t, typename circular_t = dx::midi::ump::circular>
void dx::coremidi::stream< device_t, circular_t >::transmit ( )
inlineprotectednoexcept

circular data driven streaming out thread

transmit is seen from the based circular buffer perspective coremidi::stream::transmit() -> CoreMIDI MIDISendEventList: send to OS CoreMIDI MIDI Output endpoint If the receiving endpoint is an dx::coremidi::server::pin the MIDI data is received by coremidi::server::pin::receive() and there usually be used by a HW device device to send it out to its HW MIDI Output ports

flow control & signalisation this->data[dx::stream::direction::out] -> signals data draining(out) this->data[dx::stream::direction::in] -> waits for data arrival(in) ::MIDISendEventList() controls flow by stalling when endpoint buffering would be overflowing otherwise

Here is the call graph for this function:

Member Data Documentation

◆ [struct]

struct { ... } dx::stream::stream< device_t, dx::midi::ump::circular, control<object<device_t>>, event<user> >::cache
Todo
: stream::stream::cache needs to be made protected (coreaudio::device requires cache access)

◆ circular

dx::midi::ump::circular* dx::stream::stream< device_t, dx::midi::ump::circular, control<object<device_t>>, event<user> >::circular
protectedinherited

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

◆ control

dx::stream::channel::control* dx::stream::stream< device_t, dx::midi::ump::circular, control<object<device_t>>, event<user> >::control
inherited

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

◆ data

event_t dx::stream::stream< device_t, dx::midi::ump::circular, control<object<device_t>>, event<user> >::data[direction::directions]
inherited

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

◆ endpoint

template<typename device_t, typename circular_t = dx::midi::ump::circular>
::MIDIEndpointRef dx::coremidi::stream< device_t, circular_t >::endpoint {}
protected

◆ 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. The seed is the desc's own pin format, so a stream that nobody contradicts runs what it was declared with.

◆ granularity

uint32_t dx::stream::stream< device_t, dx::midi::ump::circular, control<object<device_t>>, event<user> >::granularity
inherited

◆ id

const decltype(desc::target.idx()) dx::stream::stream< device_t, dx::midi::ump::circular, control<object<device_t>>, event<user> >::id
inherited

◆ latency

uint32_t dx::stream::stream< device_t, dx::midi::ump::circular, control<object<device_t>>, event<user> >::latency
inherited

◆ linesize

uint32_t dx::stream::stream< device_t, dx::midi::ump::circular, control<object<device_t>>, event<user> >::linesize
inherited

◆ monitor

◆ port

template<typename device_t, typename circular_t = dx::midi::ump::circular>
::MIDIPortRef dx::coremidi::stream< device_t, circular_t >::port {}
protected

◆ protocol

template<typename device_t, typename circular_t = dx::midi::ump::circular>
::MIDIProtocolID dx::coremidi::stream< device_t, circular_t >::protocol = ::kMIDIProtocol_1_0
protected

what the port speaks: MIDI 1.0 in Universal MIDI Packets, so a legacy endpoint is translated by CoreMIDI and a MIDI 2.0 one keeps its own words

◆ samplerate

decltype(device_t::samplerate) & dx::stream::stream< device_t, dx::midi::ump::circular, control<object<device_t>>, event<user> >::samplerate
inherited

◆ status

os_result dx::stream::stream< device_t, dx::midi::ump::circular, control<object<device_t>>, event<user> >::status
inherited

◆ ticking

bool dx::stream::stream< device_t, dx::midi::ump::circular, control<object<device_t>>, event<user> >::ticking
inherited

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


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

(c) copyright 2009 dynamic acoustics e.U. generated on

a closed source license may be obtained by requesting a written permission from dynamic acoustics e.U.
however - governmental use generally and military use especially is strictly prohibited though.