mirror of
https://github.com/Ardour/ardour.git
synced 2026-01-05 21:25:46 +01:00
more details for VST support
git-svn-id: svn://localhost/ardour2/trunk@630 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
912da52a53
commit
4d3e06f29d
9 changed files with 1230 additions and 0 deletions
181
libs/fst/vsti.c
Normal file
181
libs/fst/vsti.c
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* VST instrument support
|
||||
*
|
||||
* Derived from code that was marked:
|
||||
* Copyright (C) Kjetil S. Matheussen 2004 (k.s.matheussen@notam02.no)
|
||||
* Alsa-seq midi-code made by looking at the jack-rack source made by Bob Ham.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id: vsti.c,v 1.2 2004/04/07 01:56:23 pauld Exp $
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <jackvst.h>
|
||||
#include <vst/aeffectx.h>
|
||||
|
||||
snd_seq_t *
|
||||
create_sequencer (const char* client_name, bool isinput)
|
||||
{
|
||||
snd_seq_t * seq;
|
||||
int err;
|
||||
|
||||
if ((err = snd_seq_open (&seq, "default", SND_SEQ_OPEN_DUPLEX, 0)) != 0) {
|
||||
fst_error ("Could not open ALSA sequencer, aborting\n\n%s\n\n"
|
||||
"Make sure you have configure ALSA properly and that\n"
|
||||
"/proc/asound/seq/clients exists and contains relevant\n"
|
||||
"devices (%s).",
|
||||
snd_strerror (err));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
snd_seq_set_client_name (seq, client_name);
|
||||
|
||||
if ((err = snd_seq_create_simple_port (seq, isinput? "Input" : "Output",
|
||||
(isinput? SND_SEQ_PORT_CAP_WRITE: SND_SEQ_PORT_CAP_READ)| SND_SEQ_PORT_CAP_DUPLEX |
|
||||
SND_SEQ_PORT_CAP_SUBS_READ|SND_SEQ_PORT_CAP_SUBS_WRITE,
|
||||
SND_SEQ_PORT_TYPE_APPLICATION|SND_SEQ_PORT_TYPE_SPECIFIC)) != 0) {
|
||||
fst_error ("Could not create ALSA port: %s", snd_strerror (err));
|
||||
snd_seq_close(seq);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return seq;
|
||||
}
|
||||
|
||||
static void
|
||||
queue_midi (JackVST *jvst, int val1, int val2, int val3)
|
||||
{
|
||||
struct VstMidiEvent *pevent;
|
||||
jack_ringbuffer_data_t vec[2];
|
||||
|
||||
jack_ringbuffer_get_write_vector (jvst->event_queue, vec);
|
||||
|
||||
if (vec[0].len < sizeof (struct VstMidiEvent)) {
|
||||
fst_error ("event queue has no write space");
|
||||
return;
|
||||
}
|
||||
|
||||
pevent = (struct VstMidiEevent *) vec[0].buf;
|
||||
|
||||
// printf("note: %d\n",note);
|
||||
|
||||
pevent->type = kVstMidiType;
|
||||
pevent->byteSize = 24;
|
||||
pevent->deltaFrames = 0;
|
||||
pevent->flags = 0;
|
||||
pevent->detune = 0;
|
||||
pevent->noteLength = 0;
|
||||
pevent->noteOffset = 0;
|
||||
pevent->reserved1 = 0;
|
||||
pevent->reserved2 = 0;
|
||||
pevent->noteOffVelocity = 0;
|
||||
pevent->midiData[0] = val1;
|
||||
pevent->midiData[1] = val2;
|
||||
pevent->midiData[2] = val3;
|
||||
pevent->midiData[3] = 0;
|
||||
|
||||
//printf("Sending: %x %x %x\n",val1,val2,val3);
|
||||
|
||||
jack_ringbuffer_write_advance (jvst->event_queue, sizeof (struct VstMidiEvent));
|
||||
}
|
||||
|
||||
void *midireceiver(void *arg)
|
||||
{
|
||||
snd_seq_event_t *event;
|
||||
JackVST *jvst = (JackVST* )arg;
|
||||
int val;
|
||||
|
||||
while (1) {
|
||||
|
||||
snd_seq_event_input (jvst->seq, &event);
|
||||
|
||||
if (jvst->midiquit) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch(event->type){
|
||||
case SND_SEQ_EVENT_NOTEON:
|
||||
queue_midi(jvst,0x90+event->data.note.channel,event->data.note.note,event->data.note.velocity);
|
||||
//printf("Noteon, channel: %d note: %d vol: %d\n",event->data.note.channel,event->data.note.note,event->data.note.velocity);
|
||||
break;
|
||||
case SND_SEQ_EVENT_NOTEOFF:
|
||||
queue_midi(jvst,0x80+event->data.note.channel,event->data.note.note,0);
|
||||
//printf("Noteoff, channel: %d note: %d vol: %d\n",event->data.note.channel,event->data.note.note,event->data.note.velocity);
|
||||
break;
|
||||
case SND_SEQ_EVENT_KEYPRESS:
|
||||
//printf("Keypress, channel: %d note: %d vol: %d\n",event->data.note.channel,event->data.note.note,event->data.note.velocity);
|
||||
queue_midi(jvst,0xa0+event->data.note.channel,event->data.note.note,event->data.note.velocity);
|
||||
break;
|
||||
case SND_SEQ_EVENT_CONTROLLER:
|
||||
queue_midi(jvst,0xb0+event->data.control.channel,event->data.control.param,event->data.control.value);
|
||||
//printf("Control: %d %d %d\n",event->data.control.channel,event->data.control.param,event->data.control.value);
|
||||
break;
|
||||
case SND_SEQ_EVENT_PITCHBEND:
|
||||
val=event->data.control.value + 0x2000;
|
||||
queue_midi(jvst,0xe0+event->data.control.channel,val&127,val>>7);
|
||||
//printf("Pitch: %d %d %d\n",event->data.control.channel,event->data.control.param,event->data.control.value);
|
||||
break;
|
||||
case SND_SEQ_EVENT_CHANPRESS:
|
||||
//printf("chanpress: %d %d %d\n",event->data.control.channel,event->data.control.param,event->data.control.value);
|
||||
queue_midi(jvst,0xd0+event->data.control.channel,event->data.control.value,0);
|
||||
break;
|
||||
case SND_SEQ_EVENT_PGMCHANGE:
|
||||
//printf("pgmchange: %d %d %d\n",event->data.control.channel,event->data.control.param,event->data.control.value);
|
||||
queue_midi(jvst,0xc0+event->data.control.channel,event->data.control.value,0);
|
||||
break;
|
||||
default:
|
||||
//printf("Unknown type: %d\n",event->type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void stop_midireceiver (JackVST *jvst)
|
||||
{
|
||||
int err;
|
||||
snd_seq_event_t event;
|
||||
snd_seq_t *seq2 = create_sequencer ("jfstquit", true);
|
||||
|
||||
jvst->midiquit = 1;
|
||||
|
||||
snd_seq_connect_to (seq2, 0, snd_seq_client_id (jvst->seq),0);
|
||||
snd_seq_ev_clear (&event);
|
||||
snd_seq_ev_set_direct (&event);
|
||||
snd_seq_ev_set_subs (&event);
|
||||
snd_seq_ev_set_source (&event, 0);
|
||||
snd_seq_ev_set_controller (&event,1,0x80,50);
|
||||
|
||||
if ((err = snd_seq_event_output (seq2, &event)) < 0) {
|
||||
fst_error ("cannot send stop event to midi thread: %s\n",
|
||||
snd_strerror (err));
|
||||
}
|
||||
|
||||
snd_seq_drain_output (seq2);
|
||||
snd_seq_close (seq2);
|
||||
pthread_join (jvst->midi_thread,NULL);
|
||||
snd_seq_close (jvst->seq);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue