Audacity 3.2.0
Public Member Functions | Public Attributes | List of all members
LV2AtomPortState Struct Referencefinal

State of an instance of an LV2 Atom port. More...

#include <LV2Ports.h>

Collaboration diagram for LV2AtomPortState:
[legend]

Public Member Functions

 LV2AtomPortState (LV2AtomPortPtr pPort)
 
void SendToInstance (LV2_Atom_Forge &forge, int64_t frameTime, float speed)
 Transfer incoming events from the ring buffer to the event buffer. More...
 
void ResetForInstanceOutput ()
 
void ReceiveFromInstance ()
 Take responses from the instance and send cross-thread for the dialog. More...
 
void SendToDialog (std::function< void(const LV2_Atom *atom, uint32_t size)> handler)
 Dialog can poll one ring buffer for messages at idle time. More...
 
void ReceiveFromDialog (const void *buffer, uint32_t buffer_size)
 Dialog pushes to other ring buffer when it gets a user interface event. More...
 

Public Attributes

const LV2AtomPortPtr mpPort
 
const Lilv_ptr< ZixRing, zix_ring_freemRing
 
const std::unique_ptr< uint8_t[]> mBuffer
 

Detailed Description

State of an instance of an LV2 Atom port.

Definition at line 79 of file LV2Ports.h.

Constructor & Destructor Documentation

◆ LV2AtomPortState()

LV2AtomPortState::LV2AtomPortState ( LV2AtomPortPtr  pPort)
inlineexplicit
Precondition
pPort != nullptr

Definition at line 81 of file LV2Ports.h.

82 : mpPort{ move(pPort) }
83 , mRing{ zix_ring_new(mpPort->mMinimumSize) }
84 , mBuffer{ safenew uint8_t[mpPort->mMinimumSize] }
85 {
86 assert(mpPort);
87 /*
88 There is no complementary munlock anywhere in the library!
89 Are we mis-using a class meant for plugin implementation?
90 Do we make a resource leak of physical memory pages?
91 Should we just skip this call?
92 Or is mlock a good idea we should implement in our own RingBuffer,
93 which we can also munlock in its destructor?
94 */
95 zix_ring_mlock(mRing.get());
96
98 }
#define safenew
Definition: MemoryX.h:10
ZixRing * zix_ring_new(uint32_t size)
Definition: ring.cpp:74
void zix_ring_mlock(ZixRing *ring)
Definition: ring.cpp:93
const std::unique_ptr< uint8_t[]> mBuffer
Definition: LV2Ports.h:123
const Lilv_ptr< ZixRing, zix_ring_free > mRing
Definition: LV2Ports.h:122
void ResetForInstanceOutput()
Definition: LV2Ports.cpp:78
const LV2AtomPortPtr mpPort
Definition: LV2Ports.h:121

References zix_ring_mlock().

Here is the call graph for this function:

Member Function Documentation

◆ ReceiveFromDialog()

void LV2AtomPortState::ReceiveFromDialog ( const void *  buffer,
uint32_t  buffer_size 
)

Dialog pushes to other ring buffer when it gets a user interface event.

Definition at line 121 of file LV2Ports.cpp.

123{
124 // Send event information blob from the UI to the processing thread
125 zix_ring_write(mRing.get(), buffer, buffer_size);
126}
uint32_t zix_ring_write(ZixRing *ring, const void *src, uint32_t size)
Definition: ring.cpp:201

References mRing, and zix_ring_write().

Here is the call graph for this function:

◆ ReceiveFromInstance()

void LV2AtomPortState::ReceiveFromInstance ( )

Take responses from the instance and send cross-thread for the dialog.

Definition at line 110 of file LV2Ports.cpp.

111{
112 if (!mpPort->mIsInput) {
113 const auto ring = mRing.get();
114 LV2_ATOM_SEQUENCE_FOREACH(
115 reinterpret_cast<LV2_Atom_Sequence *>(mBuffer.get()), ev
116 )
117 zix_ring_write(ring, &ev->body, ev->body.size + sizeof(LV2_Atom));
118 }
119}

References mBuffer, mpPort, mRing, and zix_ring_write().

Here is the call graph for this function:

◆ ResetForInstanceOutput()

void LV2AtomPortState::ResetForInstanceOutput ( )

Definition at line 78 of file LV2Ports.cpp.

78 {
79 using namespace LV2Symbols;
80 auto &port = mpPort;
81 if (!port->mIsInput) {
82 const auto buf = mBuffer.get();
83 *reinterpret_cast<LV2_Atom *>(buf) = { port->mMinimumSize, urid_Chunk };
84 }
85}

References mBuffer, and mpPort.

Referenced by SendToInstance().

Here is the caller graph for this function:

◆ SendToDialog()

void LV2AtomPortState::SendToDialog ( std::function< void(const LV2_Atom *atom, uint32_t size)>  handler)

Dialog can poll one ring buffer for messages at idle time.

Given function may be called multiple times

Definition at line 87 of file LV2Ports.cpp.

89{
90 const auto ring = mRing.get();
91 const auto minimumSize = mpPort->mMinimumSize;
92 const auto space = std::make_unique<char[]>(minimumSize);
93 auto atom = reinterpret_cast<LV2_Atom*>(space.get());
94 // Consume messages from the processing thread and pass to the
95 // foreign UI code, for updating output displays
96 while (zix_ring_read(ring, atom, sizeof(LV2_Atom))) {
97 uint32_t size = lv2_atom_total_size(atom);
98 if (size < minimumSize) {
99 zix_ring_read(ring,
100 LV2_ATOM_CONTENTS(LV2_Atom, atom), atom->size);
101 handler(atom, size);
102 }
103 else {
104 zix_ring_skip(ring, atom->size);
105 wxLogError(wxT("LV2 sequence buffer overflow"));
106 }
107 }
108}
wxT("CloseDown"))
uint32_t zix_ring_read(ZixRing *ring, void *dst, uint32_t size)
Definition: ring.cpp:172
uint32_t zix_ring_skip(ZixRing *ring, uint32_t size)
Definition: ring.cpp:187

References audacity::cloud::audiocom::anonymous_namespace{AuthorizationHandler.cpp}::handler, mpPort, mRing, size, wxT(), zix_ring_read(), and zix_ring_skip().

Here is the call graph for this function:

◆ SendToInstance()

void LV2AtomPortState::SendToInstance ( LV2_Atom_Forge &  forge,
int64_t  frameTime,
float  speed 
)

Transfer incoming events from the ring buffer to the event buffer.

These will be made available to each slave in the chain. In addition, reset the output Atom ports.

Definition at line 21 of file LV2Ports.cpp.

23 {
24 using namespace LV2Symbols;
25 auto &port = mpPort;
26 const auto buf = mBuffer.get();
27 if (port->mIsInput) {
28 // TAKE from an inter-thread ring buffer;
29 // PUT to an "atom forge" which is a serializer of structured information
30 // and the forge populates the buffer that the atom port was connected to
31 // and it also receives other information about speed and accumulated
32 // number of samples
33 lv2_atom_forge_set_buffer(&forge, buf, port->mMinimumSize);
34 LV2_Atom_Forge_Frame seqFrame;
35 const auto seq = reinterpret_cast<LV2_Atom_Sequence *>(
36 lv2_atom_forge_sequence_head(&forge, &seqFrame, 0));
37 if (port->mWantsPosition) {
38 lv2_atom_forge_frame_time(&forge, frameTime);
39 LV2_Atom_Forge_Frame posFrame;
40 lv2_atom_forge_object(&forge, &posFrame, 0, urid_Position);
41 lv2_atom_forge_key(&forge, urid_Speed);
42 lv2_atom_forge_float(&forge, speed);
43 lv2_atom_forge_key(&forge, urid_Frame);
44 lv2_atom_forge_long(&forge, frameTime);
45 lv2_atom_forge_pop(&forge, &posFrame);
46 }
47 // Copy event information from the UI thread into plugin's atom input,
48 // inserting frame time
49 const auto ring = mRing.get();
50 LV2_Atom atom;
51 while (zix_ring_read(ring, &atom, sizeof(atom))) {
52 if (forge.offset + sizeof(LV2_Atom_Event) + atom.size < forge.size){
53 lv2_atom_forge_frame_time(&forge, frameTime);
54 lv2_atom_forge_write(&forge, &atom, sizeof(atom));
55 zix_ring_read(ring, &forge.buf[forge.offset], atom.size);
56 forge.offset += atom.size;
57 seq->atom.size += atom.size;
58 }
59 else {
60 zix_ring_skip(ring, atom.size);
61 wxLogError(wxT("LV2 sequence buffer overflow"));
62 }
63 }
64 lv2_atom_forge_pop(&forge, &seqFrame);
65#if 0
66 LV2_ATOM_SEQUENCE_FOREACH(seq, ev) {
67 auto o = reinterpret_cast<LV2_Atom_Object *>(&ev->body);
68 wxLogDebug(wxT("ev = %lld ev.size %d ev.type %d"), ev->time.frames, ev->body.size, ev->body.type);
69 }
70#endif
71 }
72 else
73 // PRL: I'm not sure why this must be done both before lilv_instance_run
74 // and after, but that's the legacy
76}

References mBuffer, mpPort, mRing, ResetForInstanceOutput(), wxT(), zix_ring_read(), and zix_ring_skip().

Here is the call graph for this function:

Member Data Documentation

◆ mBuffer

const std::unique_ptr<uint8_t[]> LV2AtomPortState::mBuffer

Definition at line 123 of file LV2Ports.h.

Referenced by ReceiveFromInstance(), ResetForInstanceOutput(), and SendToInstance().

◆ mpPort

const LV2AtomPortPtr LV2AtomPortState::mpPort

◆ mRing

const Lilv_ptr<ZixRing, zix_ring_free> LV2AtomPortState::mRing

Definition at line 122 of file LV2Ports.h.

Referenced by ReceiveFromDialog(), ReceiveFromInstance(), SendToDialog(), and SendToInstance().


The documentation for this struct was generated from the following files: