Skip to content

Commit

Permalink
* Ensure frame offsets for MIDI events get passed through to the VST …
Browse files Browse the repository at this point in the history
…properly.

* Make plugin test whether there are any candidate DLLs in VST_PATH, and
  omit to run the scanner if there are none.
  • Loading branch information
cannam committed Oct 8, 2004
1 parent 5f3adb6 commit b1593d3
Show file tree
Hide file tree
Showing 12 changed files with 101 additions and 37 deletions.
2 changes: 1 addition & 1 deletion dssi-vst-scanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmdline, int cmdshow)
{
char *destFile = 0;

cout << "DSSI VST plugin scanner v0.2" << endl;
cout << "DSSI VST plugin scanner v0.3" << endl;
cout << "Copyright (c) 2004 Chris Cannam - Fervent Software" << endl;

if (cmdline && cmdline[0]) destFile = strdup(cmdline);
Expand Down
21 changes: 10 additions & 11 deletions dssi-vst-server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ class RemoteVSTServer : public RemotePluginServer
virtual void setCurrentProgram(int);

virtual bool hasMIDIInput() { return m_hasMIDI; }
virtual void sendMIDIData(unsigned char *data, int length);
virtual void sendMIDIData(unsigned char *data,
int *frameOffsets,
int events);

virtual void process(float **inputs, float **outputs) {
inProcessThread = true;
Expand Down Expand Up @@ -260,10 +262,8 @@ RemoteVSTServer::setCurrentProgram(int p)
}

void
RemoteVSTServer::sendMIDIData(unsigned char *data, int len)
RemoteVSTServer::sendMIDIData(unsigned char *data, int *frameOffsets, int events)
{
std::cerr << "host: sendMIDIData length " << len << std::endl;

#define MIDI_EVENT_BUFFER_COUNT 1024
static VstMidiEvent vme[MIDI_EVENT_BUFFER_COUNT];
static char evbuf[sizeof(VstMidiEvent *) * MIDI_EVENT_BUFFER_COUNT +
Expand All @@ -273,20 +273,19 @@ RemoteVSTServer::sendMIDIData(unsigned char *data, int len)
vstev->reserved = 0;

int ix = 0;
int count = len/3;

if (count > MIDI_EVENT_BUFFER_COUNT) {
std::cerr << "vstserv: WARNING: " << count << " MIDI events received "
if (events > MIDI_EVENT_BUFFER_COUNT) {
std::cerr << "vstserv: WARNING: " << events << " MIDI events received "
<< "for " << MIDI_EVENT_BUFFER_COUNT << "-event buffer"
<< std::endl;
count = MIDI_EVENT_BUFFER_COUNT;
events = MIDI_EVENT_BUFFER_COUNT;
}

while (ix < count) {
while (ix < events) {

vme[ix].type = kVstMidiType;
vme[ix].byteSize = 24;
vme[ix].deltaFrames = 0;
vme[ix].deltaFrames = (frameOffsets ? frameOffsets[ix] : 0);
vme[ix].flags = 0;
vme[ix].noteLength = 0;
vme[ix].noteOffset = 0;
Expand All @@ -311,7 +310,7 @@ RemoteVSTServer::sendMIDIData(unsigned char *data, int len)
++ix;
}

vstev->numEvents = count;
vstev->numEvents = events;
if (!m_plugin->dispatcher(m_plugin, effProcessEvents, 0, 0, vstev, 0)) {
cerr << "WARNING: " << ix << " MIDI event(s) rejected by plugin" << endl;
}
Expand Down
15 changes: 11 additions & 4 deletions dssi-vst.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
#include <string>
#include <iostream>

#define MIDI_BUFFER_SIZE 1024
// Should be divisible by three
#define MIDI_BUFFER_SIZE 1023

class DSSIVSTPluginInstance
{
Expand Down Expand Up @@ -68,6 +69,7 @@ class DSSIVSTPluginInstance
unsigned long m_programCount;

unsigned char m_decodeBuffer[MIDI_BUFFER_SIZE];
int m_frameOffsetsBuffer[MIDI_BUFFER_SIZE / 3];
snd_midi_event_t *m_alsaDecoder;

bool m_pendingProgram;
Expand Down Expand Up @@ -332,12 +334,17 @@ DSSIVSTPluginInstance::runSynth(unsigned long sampleCount,
if (m_alsaDecoder) {

unsigned long index = 0;
unsigned long i;

for (unsigned long i = 0; i < eventCount; ++i) {
for (i = 0; i < eventCount; ++i) {

snd_seq_event_t *ev = &events[i];

if (index >= MIDI_BUFFER_SIZE - 4) break;

std::cout << "DSSIVSTPluginInstance::runSynth: event at offset " << ev->time.tick << std::endl;

m_frameOffsetsBuffer[i] = ev->time.tick;

long count = snd_midi_event_decode(m_alsaDecoder,
m_decodeBuffer + index,
Expand All @@ -358,7 +365,7 @@ DSSIVSTPluginInstance::runSynth(unsigned long sampleCount,
}

if (index > 0) {
m_plugin->sendMIDIData(m_decodeBuffer, index);
m_plugin->sendMIDIData(m_decodeBuffer, m_frameOffsetsBuffer, i);
}
}
} catch (RemotePluginClosedException) {
Expand Down
24 changes: 17 additions & 7 deletions rdwrops.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,16 +119,26 @@ rdwr_readFloat(int fd, const char *file, int line)
}

extern unsigned char *
rdwr_readMIDIData(int fd, int &len, const char *file, int line)
rdwr_readMIDIData(int fd, int **frameoffsets, int &events, const char *file, int line)
{
static unsigned char *buf = 0;
static int bufLen = 0;
rdwr_tryRead(fd, &len, sizeof(int), file, line);
if (len > bufLen) {
static int *frameoffbuf = 0;
static int bufEvts = 0;

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

if (events > bufEvts) {
delete buf;
buf = new unsigned char[len];
bufLen = len;
delete frameoffbuf;
buf = new unsigned char[events * 3];
frameoffbuf = new int[events];
bufEvts = events;
}
rdwr_tryRead(fd, buf, len, file, line);

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

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

4 changes: 2 additions & 2 deletions rdwrops.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ extern void rdwr_writeInt(int fd, int i, const char *file, int line);
extern int rdwr_readInt(int fd, const char *file, int line);
extern void rdwr_writeFloat(int fd, float f, const char *file, int line);
extern float rdwr_readFloat(int fd, const char *file, int line);
extern unsigned char *rdwr_readMIDIData(int fd, int &len, const char *file, int line);
extern unsigned char *rdwr_readMIDIData(int fd, int **frameoffsets, int &events, const char *file, int line);

#define tryRead(a, b, c) rdwr_tryRead(a, b, c, __FILE__, __LINE__)
#define tryWrite(a, b, c) rdwr_tryWrite(a, b, c, __FILE__, __LINE__)
Expand All @@ -30,6 +30,6 @@ extern unsigned char *rdwr_readMIDIData(int fd, int &len, const char *file, int
#define readInt(a) rdwr_readInt(a, __FILE__, __LINE__)
#define writeFloat(a, b) rdwr_writeFloat(a, b, __FILE__, __LINE__)
#define readFloat(a) rdwr_readFloat(a, __FILE__, __LINE__)
#define readMIDIData(a, b) rdwr_readMIDIData(a, b, __FILE__, __LINE__)
#define readMIDIData(a, b, c) rdwr_readMIDIData(a, b, c, __FILE__, __LINE__)

#endif
2 changes: 1 addition & 1 deletion remoteplugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#ifndef REMOTE_PLUGIN_H
#define REMOTE_PLUGIN_H

static const float RemotePluginVersion = 0.9;
static const float RemotePluginVersion = 0.95;

enum RemotePluginDebugLevel {
RemotePluginDebugNone,
Expand Down
16 changes: 12 additions & 4 deletions remotepluginclient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -382,12 +382,20 @@ RemotePluginClient::setCurrentProgram(int n)
}

void
RemotePluginClient::sendMIDIData(unsigned char *data, int length)
RemotePluginClient::sendMIDIData(unsigned char *data, int *frameoffsets, int events)
{
std::cerr << "client: sendMIDIData length " << length << std::endl;
writeOpcode(m_processFd, RemotePluginSendMIDIData);
writeInt(m_processFd, length);
tryWrite(m_processFd, data, length);
writeInt(m_processFd, events);
tryWrite(m_processFd, data, events * 3);

if (!frameoffsets) {
// This should not happen with a good client, but we'd better
// cope as well as possible with the lazy ol' degenerates
frameoffsets = (int *)alloca(events * sizeof(int));
memset(frameoffsets, 0, events * sizeof(int));
}

tryWrite(m_processFd, frameoffsets, events * sizeof(int));
}

void
Expand Down
4 changes: 3 additions & 1 deletion remotepluginclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ class RemotePluginClient
void setCurrentProgram(int);

bool hasMIDIInput();
void sendMIDIData(unsigned char *data, int length);

// Must be three bytes per event
void sendMIDIData(unsigned char *data, int *frameoffsets, int events);

// Either inputs or outputs may be NULL if (and only if) there are none
void process(float **inputs, float **outputs);
Expand Down
10 changes: 6 additions & 4 deletions remotepluginserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,10 +241,12 @@ RemotePluginServer::dispatchProcess()

} else if (opcode == RemotePluginSendMIDIData) {

int len = 0;
unsigned char *data = readMIDIData(m_processFd, len);
std::cerr << "server: sendMIDIData length " << len << std::endl;
sendMIDIData(data, len);
int events = 0;
int *frameoffsets = 0;
unsigned char *data = readMIDIData(m_processFd, &frameoffsets, events);
if (events && data && frameoffsets) {
sendMIDIData(data, frameoffsets, events);
}
}
}

Expand Down
3 changes: 2 additions & 1 deletion remotepluginserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ class RemotePluginServer

virtual bool hasMIDIInput() { return false; }
virtual void sendMIDIData(unsigned char *data,
int length) { return; }
int *frameOffsets,
int events) { return; }

virtual void process(float **inputs, float **outputs) = 0;

Expand Down
35 changes: 35 additions & 0 deletions remotevstclient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,41 @@ RemoteVSTClient::~RemoteVSTClient()
void
RemoteVSTClient::queryPlugins(std::vector<PluginRecord> &plugins)
{
// First check whether there are any DLLs in the same VST path as
// the scanner uses. If not, we know immediately there are no
// plugins and we don't need to run the (Wine-based) scanner.

std::vector<std::string> vstPath = Paths::getPath
("VST_PATH", "/usr/local/lib/vst:/usr/lib/vst", "/vst");

bool haveDll = false;

for (size_t i = 0; i < vstPath.size(); ++i) {

std::string vstDir = vstPath[i];
DIR *directory = opendir(vstDir.c_str());
if (!directory) continue;
struct dirent *entry;

while ((entry = readdir(directory))) {

std::string libname = entry->d_name;

if (libname[0] != '.' &&
libname.length() >= 5 &&
(libname.substr(libname.length() - 4) == ".dll" ||
libname.substr(libname.length() - 4) == ".DLL")) {
haveDll = true;
break;
}
}

closedir(directory);
if (haveDll) break;
}

if (!haveDll) return;

char fifoFile[60];

sprintf(fifoFile, "/tmp/rplugin_qry_XXXXXX");
Expand Down
2 changes: 1 addition & 1 deletion vstsynth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ jackProcess(jack_nframes_t nframes, void *arg)
pthread_mutex_lock(&pluginMutex);

if (alsaDecoderIndex > 0) {
plugin->sendMIDIData(alsaDecoderBuffer, alsaDecoderIndex);
plugin->sendMIDIData(alsaDecoderBuffer, 0, alsaDecoderIndex);
alsaDecoderIndex = 0;
}

Expand Down

0 comments on commit b1593d3

Please sign in to comment.