Skip to content
This repository was archived by the owner on Feb 13, 2019. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@

dssi-vst_gui
vsthost

*.swp
107 changes: 68 additions & 39 deletions vsthost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,13 +189,13 @@ alsaSeqCallback(snd_seq_t *alsaSeqHandle)
}

int
openAlsaSeq(const char *pluginName)
openAlsaSeq(const char *clientName)
{
int portid;
char alsaName[75];

if (pluginName[0]) {
sprintf(alsaName, "%s VST", pluginName);
if (clientName[0]) {
sprintf(alsaName, "%s VST", clientName);
} else {
sprintf(alsaName, "VST Host");
}
Expand Down Expand Up @@ -330,27 +330,41 @@ shutdownJack(void *arg)
}

int
openJack(const char *pluginName)
openJack(const char * pluginName, bool unique)
{
const char **ports = 0;
char jackName[26];
char tmpbuf[21];
int i = 0, j = 0;

for (i = 0; i < 20 && pluginName[i]; ++i) {
if (isalpha(pluginName[i])) {
tmpbuf[j] = tolower(pluginName[i]);
++j;
}
}
tmpbuf[j] = '\0';
snprintf(jackName, 26, "vst_%s", tmpbuf);

if ((jackData.client = jack_client_open(jackName, JackNullOption, NULL)) == 0) {
fprintf(stderr, "ERROR: Failed to connect to JACK server -- jackd not running?\n");
return 1;
// A full port name has the format "<client>:<port>"
// and is terminated by the usual \0 character.
// http://jackaudio.org/files/docs/html/group__PortFunctions.html
// Here we allocate half of the remaining characters to each part
// of the "client:port" pair. If needed, this can be redistributed.

int jackNameSize = (jack_port_name_size() - 2) / 2 + 1;
int portNameSize = (jack_port_name_size() - 2) / 2 + 1;
char jackName[jackNameSize];
char portName[portNameSize];
jack_status_t jackStatus;

snprintf(jackName, jackNameSize, "%s", pluginName);

jackData.client = jack_client_open(
jackName,
unique ? JackUseExactName : JackNullOption,
&jackStatus);

if (jackData.client == 0) {
if (unique) {
fprintf(stderr, "ERROR: Failed to initialize JACK -- "
"name not unique or jackd not running?");
} else {
fprintf(stderr, "ERROR: Failed to initialize JACK client -- "
"jackd not running?\n");
}
return 1;
}

fprintf(stderr, "JACK client name: %s\n", jack_get_client_name(jackData.client));

jack_set_process_callback(jackData.client, jackProcess, 0);
jack_on_shutdown(jackData.client, shutdownJack, 0);

Expand All @@ -360,25 +374,24 @@ openJack(const char *pluginName)
plugin->setSampleRate(jackData.sample_rate);
plugin->setBufferSize(jackData.buffer_size);

ports = jack_get_ports
(jackData.client, NULL, NULL, JackPortIsPhysical | JackPortIsInput);
const char ** ports = jack_get_ports(
jackData.client, NULL, NULL, JackPortIsPhysical | JackPortIsInput);

jackData.input_count = plugin->getInputCount();
jackData.output_count = plugin->getOutputCount();

static char portName[100];

if (jackData.input_count > 0) {

jackData.input_ports = new jack_port_t*[jackData.input_count];
jackData.input_buffers = new float*[jackData.input_count];

for (int i = 0; i < jackData.input_count; ++i) {
jackData.input_buffers[i] = 0;
snprintf(portName, 100, "in_%d", i+1);
snprintf(portName, portNameSize, "in_%d", i+1);
jackData.input_ports[i] = jack_port_register
(jackData.client, portName,
JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
fprintf(stderr, "JACK input port: %s\n", portName);
}

} else {
Expand All @@ -393,10 +406,11 @@ openJack(const char *pluginName)

for (int i = 0; i < jackData.output_count; ++i) {
jackData.output_buffers[i] = 0;
snprintf(portName, 100, "out_%d", i+1);
snprintf(portName, portNameSize, "out_%d", i+1);
jackData.output_ports[i] = jack_port_register
(jackData.client, portName,
JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
fprintf(stderr, "JACK output port: %s\n", portName);
}

} else {
Expand Down Expand Up @@ -453,27 +467,40 @@ closeJack()
void
usage()
{
fprintf(stderr, "Usage: vsthost [-n] <dll>\n -n No GUI\n");
const char * usage_text =
"Usage: vsthost [-n] [-c <name>] [-u] <dll>\n"
" -n No GUI\n"
" -c Set client name\n"
" -u Fail if name is not unique\n"
" <dll> Path to VST DLL\n\n"
"Environment: DSSI_PATH VST_PATH";
fprintf(stderr, usage_text);
exit(2);
}

int
main(int argc, char **argv)
{
char *dllname = 0;
bool gui = true;

int npfd;
struct pollfd *pfd;
char * dllname = 0;
bool gui = true;
bool unique = false;
int npfd;
struct pollfd * pfd;
std::string clientName = "";

while (1) {
int c = getopt(argc, argv, "nd:");
int c = getopt(argc, argv, "nd:c:u");

if (c == -1) break;
else if (c == 'n') {
if (c == -1) {
break;
} else if (c == 'n') {
gui = false;
} else if (c == 'd') {
fprintf(stderr, "NOTE: Ignoring unsupported -d option for backward compatibility\n");
} else if (c == 'c') {
clientName = optarg;
} else if (c == 'u') {
unique = true;
} else {
usage();
}
Expand Down Expand Up @@ -505,8 +532,6 @@ main(int argc, char **argv)
bail(0);
}

std::string pluginName = plugin->getName();

// prevent child threads from wanting to handle signals
sigset_t _signals;
sigemptyset(&_signals);
Expand All @@ -522,13 +547,17 @@ main(int argc, char **argv)

bool hasMIDI = plugin->hasMIDIInput();

if (clientName.empty()) {
clientName = plugin->getName();
}

if (hasMIDI) {
if (openAlsaSeq(pluginName.c_str())) {
if (openAlsaSeq(clientName.c_str())) {
plugin->warn("Failed to connect to ALSA sequencer MIDI interface");
bail(0);
}
}
if (openJack(pluginName.c_str())) {
if (openJack(clientName.c_str(), unique)) {
plugin->warn("Failed to connect to JACK audio server (jackd not running?)");
bail(0);
}
Expand Down