Skip to content

Commit

Permalink
Merge from branch "hard-rt-support"
Browse files Browse the repository at this point in the history
  • Loading branch information
cannam committed Jun 19, 2013
2 parents feef4af + 947e907 commit 3b3bbd8
Show file tree
Hide file tree
Showing 13 changed files with 401 additions and 203 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ distclean: clean
rm -f $(TARGETS) dssi-vst-scanner dssi-vst-server *~ *.bak

%.exe.so: %.cpp libremoteplugin.w32.a $(HEADERS)
wineg++ -m32 $(CXXFLAGS) $< -o $* $(LDFLAGS) -L. -lremoteplugin.w32 -lpthread
wineg++ -m32 $(CXXFLAGS) $< -o $* $(LDFLAGS) -L. -lremoteplugin.w32 -lpthread -lrt

libremoteplugin.a: remotepluginclient.o remotepluginserver.o rdwrops.o paths.o
ar r $@ $^
Expand Down
6 changes: 0 additions & 6 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,6 @@ Bad points:
plugins would cope better with this by having the server take
ownership of such resources instead of the DSSI plugin.

* The comms model dssi-vst uses introduces a fixed latency equal to
the JACK period size, as well as any existing latency in the VST
plugin. (The fixed latency is exposed through the _latency output
control port. Does anyone know how to find out the latency of a
VST plugin?)


Licence
-------
Expand Down
7 changes: 2 additions & 5 deletions dssi-vst.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

#include "remotevstclient.h"
#include "rdwrops.h"

#include <ladspa.h>
#include <dssi.h>
Expand All @@ -21,9 +22,6 @@
#include <string.h>
#include <stdlib.h>

// Should be divisible by three
#define MIDI_BUFFER_SIZE 1023

class DSSIVSTPluginInstance
{
public:
Expand Down Expand Up @@ -341,7 +339,6 @@ DSSIVSTPluginInstance::run(unsigned long sampleCount)
if (sampleCount != m_lastSampleCount) {
m_plugin->setBufferSize(sampleCount);
m_lastSampleCount = sampleCount;
if (m_latencyOut) *m_latencyOut = sampleCount;
}

int modifiedCount = 0;
Expand Down Expand Up @@ -496,7 +493,7 @@ DSSIVSTPlugin::DSSIVSTPlugin()

ldesc->UniqueID = 6666 + p;
ldesc->Label = label;
ldesc->Properties = 0;
ldesc->Properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
ldesc->Name = strdup(std::string(rec.pluginName + " VST").c_str());
ldesc->Maker = strdup(rec.vendorName.c_str());
ldesc->Copyright = strdup(ldesc->Maker);
Expand Down
36 changes: 36 additions & 0 deletions paths.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@

#include <iostream>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

std::vector<std::string>
Paths::getPath(std::string envVar, std::string deflt, std::string defltHomeRelPath)
Expand Down Expand Up @@ -39,3 +44,34 @@ Paths::getPath(std::string envVar, std::string deflt, std::string defltHomeRelPa

return pathList;
}

// Behaves like mkstemp, but for shared memory.
int shm_mkstemp(char *fileBase)
{
const char charSet[] = "abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789";
int size = strlen(fileBase);
if (size < 6) {
errno = EINVAL;
return -1;
}

if (strcmp(fileBase + size - 6, "XXXXXX") != 0) {
errno = EINVAL;
return -1;
}

while (1) {
for (int c = size - 6; c < size; c++) {
// Note the -1 to avoid the trailing '\0' in charSet.
fileBase[c] = charSet[rand() % (sizeof(charSet) - 1)];
}
int fd = shm_open(fileBase, O_RDWR | O_CREAT | O_EXCL, 0600);
if (fd >= 0) {
return fd;
} else if (errno != EEXIST) {
return -1;
}
}
}
2 changes: 2 additions & 0 deletions paths.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ class Paths
std::string defltHomeRelPath);
};

int shm_mkstemp(char *fileBase);

#endif
157 changes: 127 additions & 30 deletions rdwrops.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@

#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <cstdio>
#include <iostream>

//#define DEBUG_RDWR 1

extern void
void
rdwr_tryRead(int fd, void *buf, size_t count, const char *file, int line)
{
ssize_t r = 0;
Expand Down Expand Up @@ -51,7 +53,7 @@ rdwr_tryRead(int fd, void *buf, size_t count, const char *file, int line)
#endif
}

extern void
void
rdwr_tryWrite(int fd, const void *buf, size_t count, const char *file, int line)
{
ssize_t w = write(fd, buf, count);
Expand All @@ -75,22 +77,94 @@ rdwr_tryWrite(int fd, const void *buf, size_t count, const char *file, int line)
#endif
}

extern void
rdwr_writeOpcode(int fd, RemotePluginOpcode opcode, const char *file, int line)
void
rdwr_tryRead(RingBuffer *ringbuf, void *buf, size_t count, const char *file, int line)
{
char *charbuf = static_cast<char *>(buf);
size_t tail = ringbuf->tail;
size_t head = ringbuf->head;
size_t wrap = 0;

if (head <= tail) {
wrap = SHM_RING_BUFFER_SIZE;
}
if (head - tail + wrap < count) {
throw RemotePluginClosedException();
}

size_t readto = tail + count;
if (readto >= SHM_RING_BUFFER_SIZE) {
readto -= SHM_RING_BUFFER_SIZE;
size_t firstpart = SHM_RING_BUFFER_SIZE - tail;
memcpy(charbuf, ringbuf->buf + tail, firstpart);
memcpy(charbuf + firstpart, ringbuf->buf, readto);
} else {
memcpy(charbuf, ringbuf->buf + tail, count);
}
ringbuf->tail = readto;
}

void
rdwr_tryWrite(RingBuffer *ringbuf, const void *buf, size_t count, const char *file, int line)
{
const char *charbuf = static_cast<const char *>(buf);
size_t written = ringbuf->written;
size_t tail = ringbuf->tail;
size_t wrap = 0;

if (tail <= written) {
wrap = SHM_RING_BUFFER_SIZE;
}
if (tail - written + wrap < count) {
std::cerr << "Operation ring buffer full! Dropping events." << std::endl;
ringbuf->invalidateCommit = true;
return;
}

size_t writeto = written + count;
if (writeto >= SHM_RING_BUFFER_SIZE) {
writeto -= SHM_RING_BUFFER_SIZE;
size_t firstpart = SHM_RING_BUFFER_SIZE - written;
memcpy(ringbuf->buf + written, charbuf, firstpart);
memcpy(ringbuf->buf, charbuf + firstpart, writeto);
} else {
memcpy(ringbuf->buf + written, charbuf, count);
}
ringbuf->written = writeto;
}

void
rdwr_commitWrite(RingBuffer *ringbuf, const char *file, int line)
{
if (ringbuf->invalidateCommit) {
ringbuf->written = ringbuf->head;
ringbuf->invalidateCommit = false;
} else {
ringbuf->head = ringbuf->written;
}
}

bool dataAvailable(RingBuffer *ringbuf)
{
return ringbuf->tail != ringbuf->head;
}

template <typename T> void
rdwr_writeOpcode(T fd, RemotePluginOpcode opcode, const char *file, int line)
{
rdwr_tryWrite(fd, &opcode, sizeof(RemotePluginOpcode), file, line);
}

extern void
rdwr_writeString(int fd, const std::string &str, const char *file, int line)
template <typename T> void
rdwr_writeString(T fd, const std::string &str, const char *file, int line)
{
int len = str.length();
rdwr_tryWrite(fd, &len, sizeof(int), file, line);
rdwr_tryWrite(fd, str.c_str(), len, file, line);
}

extern std::string
rdwr_readString(int fd, const char *file, int line)
template <typename T> std::string
rdwr_readString(T fd, const char *file, int line)
{
int len;
static char *buf = 0;
Expand All @@ -106,56 +180,79 @@ rdwr_readString(int fd, const char *file, int line)
return std::string(buf);
}

extern void
rdwr_writeInt(int fd, int i, const char *file, int line)
template <typename T> void
rdwr_writeInt(T fd, int i, const char *file, int line)
{
rdwr_tryWrite(fd, &i, sizeof(int), file, line);
}

extern int
rdwr_readInt(int fd, const char *file, int line)
template <typename T> int
rdwr_readInt(T fd, const char *file, int line)
{
int i = 0;
rdwr_tryRead(fd, &i, sizeof(int), file, line);
return i;
}

extern void
rdwr_writeFloat(int fd, float f, const char *file, int line)
template <typename T> void
rdwr_writeFloat(T fd, float f, const char *file, int line)
{
rdwr_tryWrite(fd, &f, sizeof(float), file, line);
}

extern float
rdwr_readFloat(int fd, const char *file, int line)
template <typename T> float
rdwr_readFloat(T fd, const char *file, int line)
{
float f = 0;
rdwr_tryRead(fd, &f, sizeof(float), file, line);
return f;
}

extern unsigned char *
rdwr_readMIDIData(int fd, int **frameoffsets, int &events, const char *file, int line)
template <typename T> unsigned char *
rdwr_readMIDIData(T fd, int **frameoffsets, int &events, const char *file, int line)
{
static unsigned char *buf = 0;
static int *frameoffbuf = 0;
static int bufEvts = 0;
static unsigned char buf[MIDI_BUFFER_SIZE * 3];
static int frameoffbuf[MIDI_BUFFER_SIZE];

rdwr_tryRead(fd, &events, sizeof(int), file, line);

if (events > bufEvts) {
delete buf;
delete frameoffbuf;
buf = new unsigned char[events * 3];
frameoffbuf = new int[events];
bufEvts = events;
}

rdwr_tryRead(fd, buf, events * 3, file, line);
rdwr_tryRead(fd, frameoffbuf, events * sizeof(int), file, line);

if (frameoffsets) *frameoffsets = frameoffbuf;
return buf;
}

template
void rdwr_writeOpcode(int fd, RemotePluginOpcode opcode, const char *file, int line);
template
void rdwr_writeString(int fd, const std::string &str, const char *file, int line);
template
std::string rdwr_readString(int fd, const char *file, int line);
template
void rdwr_writeInt(int fd, int i, const char *file, int line);
template
int rdwr_readInt(int fd, const char *file, int line);
template
void rdwr_writeFloat(int fd, float f, const char *file, int line);
template
float rdwr_readFloat(int fd, const char *file, int line);
template
unsigned char *rdwr_readMIDIData(int fd, int **frameoffsets, int &events, const char *file, int line);

template
void rdwr_writeOpcode(RingBuffer *ringbuf, RemotePluginOpcode opcode, const char *file, int line);
template
void rdwr_writeString(RingBuffer *ringbuf, const std::string &str, const char *file, int line);
template
std::string rdwr_readString(RingBuffer *ringbuf, const char *file, int line);
template
void rdwr_writeInt(RingBuffer *ringbuf, int i, const char *file, int line);
template
int rdwr_readInt(RingBuffer *ringbuf, const char *file, int line);
template
void rdwr_writeFloat(RingBuffer *ringbuf, float f, const char *file, int line);
template
float rdwr_readFloat(RingBuffer *ringbuf, const char *file, int line);
template
unsigned char *rdwr_readMIDIData(RingBuffer *ringbuf, int **frameoffsets, int &events, const char *file, int line);

Loading

0 comments on commit 3b3bbd8

Please sign in to comment.