2 * VST instrument support
4 * Derived from code that was marked:
5 * Copyright (C) Kjetil S. Matheussen 2004 (k.s.matheussen@notam02.no)
6 * Alsa-seq midi-code made by looking at the jack-rack source made by Bob Ham.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 * $Id: vsti.c,v 1.2 2004/04/07 01:56:23 pauld Exp $
33 #include <vst/aeffectx.h>
36 create_sequencer (const char* client_name, bool isinput)
41 if ((err = snd_seq_open (&seq, "default", SND_SEQ_OPEN_DUPLEX, 0)) != 0) {
42 fst_error ("Could not open ALSA sequencer, aborting\n\n%s\n\n"
43 "Make sure you have configure ALSA properly and that\n"
44 "/proc/asound/seq/clients exists and contains relevant\n"
50 snd_seq_set_client_name (seq, client_name);
52 if ((err = snd_seq_create_simple_port (seq, isinput? "Input" : "Output",
53 (isinput? SND_SEQ_PORT_CAP_WRITE: SND_SEQ_PORT_CAP_READ)| SND_SEQ_PORT_CAP_DUPLEX |
54 SND_SEQ_PORT_CAP_SUBS_READ|SND_SEQ_PORT_CAP_SUBS_WRITE,
55 SND_SEQ_PORT_TYPE_APPLICATION|SND_SEQ_PORT_TYPE_SPECIFIC)) != 0) {
56 fst_error ("Could not create ALSA port: %s", snd_strerror (err));
65 queue_midi (JackVST *jvst, int val1, int val2, int val3)
67 struct VstMidiEvent *pevent;
68 jack_ringbuffer_data_t vec[2];
70 jack_ringbuffer_get_write_vector (jvst->event_queue, vec);
72 if (vec[0].len < sizeof (struct VstMidiEvent)) {
73 fst_error ("event queue has no write space");
77 pevent = (struct VstMidiEevent *) vec[0].buf;
79 // printf("note: %d\n",note);
81 pevent->type = kVstMidiType;
82 pevent->byteSize = 24;
83 pevent->deltaFrames = 0;
86 pevent->noteLength = 0;
87 pevent->noteOffset = 0;
88 pevent->reserved1 = 0;
89 pevent->reserved2 = 0;
90 pevent->noteOffVelocity = 0;
91 pevent->midiData[0] = val1;
92 pevent->midiData[1] = val2;
93 pevent->midiData[2] = val3;
94 pevent->midiData[3] = 0;
96 //printf("Sending: %x %x %x\n",val1,val2,val3);
98 jack_ringbuffer_write_advance (jvst->event_queue, sizeof (struct VstMidiEvent));
101 void *midireceiver(void *arg)
103 snd_seq_event_t *event;
104 JackVST *jvst = (JackVST* )arg;
109 snd_seq_event_input (jvst->seq, &event);
111 if (jvst->midiquit) {
116 case SND_SEQ_EVENT_NOTEON:
117 queue_midi(jvst,0x90+event->data.note.channel,event->data.note.note,event->data.note.velocity);
118 //printf("Noteon, channel: %d note: %d vol: %d\n",event->data.note.channel,event->data.note.note,event->data.note.velocity);
120 case SND_SEQ_EVENT_NOTEOFF:
121 queue_midi(jvst,0x80+event->data.note.channel,event->data.note.note,0);
122 //printf("Noteoff, channel: %d note: %d vol: %d\n",event->data.note.channel,event->data.note.note,event->data.note.velocity);
124 case SND_SEQ_EVENT_KEYPRESS:
125 //printf("Keypress, channel: %d note: %d vol: %d\n",event->data.note.channel,event->data.note.note,event->data.note.velocity);
126 queue_midi(jvst,0xa0+event->data.note.channel,event->data.note.note,event->data.note.velocity);
128 case SND_SEQ_EVENT_CONTROLLER:
129 queue_midi(jvst,0xb0+event->data.control.channel,event->data.control.param,event->data.control.value);
130 //printf("Control: %d %d %d\n",event->data.control.channel,event->data.control.param,event->data.control.value);
132 case SND_SEQ_EVENT_PITCHBEND:
133 val=event->data.control.value + 0x2000;
134 queue_midi(jvst,0xe0+event->data.control.channel,val&127,val>>7);
135 //printf("Pitch: %d %d %d\n",event->data.control.channel,event->data.control.param,event->data.control.value);
137 case SND_SEQ_EVENT_CHANPRESS:
138 //printf("chanpress: %d %d %d\n",event->data.control.channel,event->data.control.param,event->data.control.value);
139 queue_midi(jvst,0xd0+event->data.control.channel,event->data.control.value,0);
141 case SND_SEQ_EVENT_PGMCHANGE:
142 //printf("pgmchange: %d %d %d\n",event->data.control.channel,event->data.control.param,event->data.control.value);
143 queue_midi(jvst,0xc0+event->data.control.channel,event->data.control.value,0);
146 //printf("Unknown type: %d\n",event->type);
154 void stop_midireceiver (JackVST *jvst)
157 snd_seq_event_t event;
158 snd_seq_t *seq2 = create_sequencer ("jfstquit", true);
162 snd_seq_connect_to (seq2, 0, snd_seq_client_id (jvst->seq),0);
163 snd_seq_ev_clear (&event);
164 snd_seq_ev_set_direct (&event);
165 snd_seq_ev_set_subs (&event);
166 snd_seq_ev_set_source (&event, 0);
167 snd_seq_ev_set_controller (&event,1,0x80,50);
169 if ((err = snd_seq_event_output (seq2, &event)) < 0) {
170 fst_error ("cannot send stop event to midi thread: %s\n",
174 snd_seq_drain_output (seq2);
175 snd_seq_close (seq2);
176 pthread_join (jvst->midi_thread,NULL);
177 snd_seq_close (jvst->seq);