ardour
session_vst.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2004
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 
18 */
19 
20 #ifndef COMPILER_MSVC
21 #include <stdbool.h>
22 #endif
23 #include <cstdio>
24 
25 #include "ardour/audioengine.h"
26 #include "ardour/session.h"
27 #include "ardour/tempo.h"
30 #include "ardour/vst_types.h"
31 #ifdef WINDOWS_VST_SUPPORT
32 #include <fst.h>
33 #endif
34 
35 #include "pbd/debug.h"
36 
37 #include "i18n.h"
38 
39 #define DEBUG_CALLBACKS
40 static int debug_callbacks = -1;
41 
42 #ifdef DEBUG_CALLBACKS
43 #define SHOW_CALLBACK if (debug_callbacks) printf
44 #else
45 #define SHOW_CALLBACK(...)
46 #endif
47 
48 using namespace ARDOUR;
49 
51 const char* Session::vst_can_do_strings[] = {
52  X_("supplyIdle"),
53  X_("sendVstTimeInfo"),
54  X_("sendVstEvents"),
55  X_("sendVstMidiEvent"),
56  X_("receiveVstEvents"),
57  X_("receiveVstMidiEvent"),
58  X_("supportShell"),
59  X_("shellCategory"),
60  X_("shellCategorycurID")
61 };
62 const int Session::vst_can_do_string_count = sizeof (vst_can_do_strings) / sizeof (char*);
63 
65  AEffect* effect,
66  int32_t opcode,
67  int32_t index,
68  intptr_t value,
69  void* ptr,
70  float opt
71  )
72 {
73  static VstTimeInfo _timeInfo;
74  VSTPlugin* plug;
75  Session* session;
76 
77  if (debug_callbacks < 0) {
78  debug_callbacks = (getenv ("ARDOUR_DEBUG_VST_CALLBACKS") != 0);
79  }
80 
81  if (effect && effect->user) {
82  plug = (VSTPlugin *) (effect->user);
83  session = &plug->session();
84  SHOW_CALLBACK ("am callback 0x%p, opcode = %d, plugin = \"%s\" ", (void*) DEBUG_THREAD_SELF, opcode, plug->name());
85  } else {
86  plug = 0;
87  session = 0;
88  SHOW_CALLBACK ("am callback 0x%p, opcode = %d", (void*) DEBUG_THREAD_SELF, opcode);
89  }
90 
91  switch(opcode){
92 
94  SHOW_CALLBACK ("amc: audioMasterAutomate\n");
95  // index, value, returns 0
96  if (plug) {
97  plug->set_parameter (index, opt);
98  }
99  return 0;
100 
101  case audioMasterVersion:
102  SHOW_CALLBACK ("amc: audioMasterVersion\n");
103  // vst version, currently 2 (0 for older)
104  return 2400;
105 
107  SHOW_CALLBACK ("amc: audioMasterCurrentId\n");
108  // returns the unique id of a plug that's currently loading
109  return vst_current_loading_id;
110 
111  case audioMasterIdle:
112  SHOW_CALLBACK ("amc: audioMasterIdle\n");
113 #ifdef WINDOWS_VST_SUPPORT
114  fst_audio_master_idle();
115 #endif
116  if (effect) {
117  effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f);
118  }
119  return 0;
120 
122  SHOW_CALLBACK ("amc: audioMasterPinConnected\n");
123  // inquire if an input or output is beeing connected;
124  // index enumerates input or output counting from zero:
125  // value is 0 for input and != 0 otherwise. note: the
126  // return value is 0 for <true> such that older versions
127  // will always return true.
128  return 1;
129 
130  case audioMasterWantMidi:
131  SHOW_CALLBACK ("amc: audioMasterWantMidi\n");
132  // <value> is a filter which is currently ignored
133  if (plug && plug->get_info() != NULL) {
134  plug->get_info()->n_inputs.set_midi (1);
135  }
136  return 0;
137 
138  case audioMasterGetTime:
139  SHOW_CALLBACK ("amc: audioMasterGetTime\n");
140  // returns const VstTimeInfo* (or 0 if not supported)
141  // <value> should contain a mask indicating which fields are required
142  // (see valid masks above), as some items may require extensive
143  // conversions
144  _timeInfo.flags = 0;
145 
146  if (session) {
147  framepos_t now = session->transport_frame();
148 
149  _timeInfo.samplePos = now;
150  _timeInfo.sampleRate = session->frame_rate();
151 
152  const TempoMetric& tm (session->tempo_map().metric_at (now));
153 
154  if (value & (kVstTempoValid)) {
155  const Tempo& t (tm.tempo());
156  _timeInfo.tempo = t.beats_per_minute ();
157  _timeInfo.flags |= (kVstTempoValid);
158  }
159  if (value & (kVstTimeSigValid)) {
160  const Meter& m (tm.meter());
161  _timeInfo.timeSigNumerator = m.divisions_per_bar ();
162  _timeInfo.timeSigDenominator = m.note_divisor ();
163  _timeInfo.flags |= (kVstTimeSigValid);
164  }
165  if ((value & (kVstPpqPosValid)) || (value & (kVstBarsValid))) {
166  Timecode::BBT_Time bbt;
167 
168  try {
169  session->tempo_map().bbt_time_rt (now, bbt);
170 
171  /* PPQ = pulse per quarter
172  * VST's "pulse" is our "division".
173  *
174  * 8 divisions per bar, 1 division = quarter, so 8 quarters per bar, ppq = 1
175  * 8 divisions per bar, 1 division = eighth, so 4 quarters per bar, ppq = 2
176  * 4 divisions per bar, 1 division = quarter, so 4 quarters per bar, ppq = 1
177  * 4 divisions per bar, 1 division = half, so 8 quarters per bar, ppq = 0.5
178  * 4 divisions per bar, 1 division = fifth, so (4 * 5/4) quarters per bar, ppq = 5/4
179  *
180  * general: divs_per_bar / (note_type / 4.0)
181  */
182  double ppq_scaling = tm.meter().note_divisor() / 4.0;
183 
184  /* Note that this assumes constant meter/tempo throughout the session. Stupid VST */
185  double ppqBar = double(bbt.bars - 1) * tm.meter().divisions_per_bar();
186  double ppqBeat = double(bbt.beats - 1);
187  double ppqTick = double(bbt.ticks) / Timecode::BBT_Time::ticks_per_beat;
188 
189  ppqBar *= ppq_scaling;
190  ppqBeat *= ppq_scaling;
191  ppqTick *= ppq_scaling;
192 
193  if (value & (kVstPpqPosValid)) {
194  _timeInfo.ppqPos = ppqBar + ppqBeat + ppqTick;
195  _timeInfo.flags |= (kVstPpqPosValid);
196  }
197 
198  if (value & (kVstBarsValid)) {
199  _timeInfo.barStartPos = ppqBar;
200  _timeInfo.flags |= (kVstBarsValid);
201  }
202 
203  } catch (...) {
204  /* relax */
205  }
206  }
207 
208  if (value & (kVstSmpteValid)) {
209  Timecode::Time t;
210 
211  session->timecode_time (now, t);
212 
213  _timeInfo.smpteOffset = (t.hours * t.rate * 60.0 * 60.0) +
214  (t.minutes * t.rate * 60.0) +
215  (t.seconds * t.rate) +
216  (t.frames) +
217  (t.subframes);
218 
219  _timeInfo.smpteOffset *= 80.0; /* VST spec is 1/80th frames */
220 
221  if (session->timecode_drop_frames()) {
222  if (session->timecode_frames_per_second() == 30.0) {
223  _timeInfo.smpteFrameRate = 5;
224  } else {
225  _timeInfo.smpteFrameRate = 4; /* 29.97 assumed, thanks VST */
226  }
227  } else {
228  if (session->timecode_frames_per_second() == 24.0) {
229  _timeInfo.smpteFrameRate = 0;
230  } else if (session->timecode_frames_per_second() == 24.975) {
231  _timeInfo.smpteFrameRate = 2;
232  } else if (session->timecode_frames_per_second() == 25.0) {
233  _timeInfo.smpteFrameRate = 1;
234  } else {
235  _timeInfo.smpteFrameRate = 3; /* 30 fps */
236  }
237  }
238  _timeInfo.flags |= (kVstSmpteValid);
239  }
240 
241  if (session->transport_speed() != 0.0f) {
242  _timeInfo.flags |= (kVstTransportPlaying);
243  }
244 
245  if (session->get_play_loop()) {
246  }
247 
248  } else {
249  _timeInfo.samplePos = 0;
251  }
252 
253  return (intptr_t) &_timeInfo;
254 
256  SHOW_CALLBACK ("amc: audioMasterProcessEvents\n");
257  // VstEvents* in <ptr>
258  if (plug && plug->midi_buffer()) {
259  VstEvents* v = (VstEvents*)ptr;
260  for (int n = 0 ; n < v->numEvents; ++n) {
261  VstMidiEvent *vme = (VstMidiEvent*) (v->events[n]->dump);
262  if (vme->type == kVstMidiType) {
263  plug->midi_buffer()->push_back(vme->deltaFrames, 3, (uint8_t*)vme->midiData);
264  }
265  }
266  }
267  return 0;
268 
269  case audioMasterSetTime:
270  SHOW_CALLBACK ("amc: audioMasterSetTime\n");
271  // VstTimenfo* in <ptr>, filter in <value>, not supported
272 
273  case audioMasterTempoAt:
274  SHOW_CALLBACK ("amc: audioMasterTempoAt\n");
275  // returns tempo (in bpm * 10000) at sample frame location passed in <value>
276  if (session) {
277  const Tempo& t (session->tempo_map().tempo_at (value));
278  return t.beats_per_minute() * 1000;
279  } else {
280  return 0;
281  }
282  break;
283 
285  SHOW_CALLBACK ("amc: audioMasterGetNumAutomatableParameters\n");
286  return 0;
287 
289  SHOW_CALLBACK ("amc: audioMasterGetParameterQuantization\n");
290  // returns the integer value for +1.0 representation,
291  // or 1 if full single float precision is maintained
292  // in automation. parameter index in <value> (-1: all, any)
293  return 0;
294 
296  SHOW_CALLBACK ("amc: audioMasterIOChanged\n");
297  // numInputs and/or numOutputs has changed
298  return 0;
299 
300  case audioMasterNeedIdle:
301  SHOW_CALLBACK ("amc: audioMasterNeedIdle\n");
302  // plug needs idle calls (outside its editor window)
303  if (plug) {
304  plug->state()->wantIdle = 1;
305  }
306  return 0;
307 
309  SHOW_CALLBACK ("amc: audioMasterSizeWindow\n");
310  // index: width, value: height
311  return 0;
312 
314  SHOW_CALLBACK ("amc: audioMasterGetSampleRate\n");
315  if (session) {
316  return session->frame_rate();
317  }
318  return 0;
319 
321  SHOW_CALLBACK ("amc: audioMasterGetBlockSize\n");
322  if (session) {
323  return session->get_block_size();
324  }
325  return 0;
326 
328  SHOW_CALLBACK ("amc: audioMasterGetInputLatency\n");
329  return 0;
330 
332  SHOW_CALLBACK ("amc: audioMasterGetOutputLatency\n");
333  return 0;
334 
336  SHOW_CALLBACK ("amc: audioMasterGetPreviousPlug\n");
337  // input pin in <value> (-1: first to come), returns cEffect*
338  return 0;
339 
341  SHOW_CALLBACK ("amc: audioMasterGetNextPlug\n");
342  // output pin in <value> (-1: first to come), returns cEffect*
343 
345  SHOW_CALLBACK ("amc: audioMasterWillReplaceOrAccumulate\n");
346  // returns: 0: not supported, 1: replace, 2: accumulate
347  return 0;
348 
350  SHOW_CALLBACK ("amc: audioMasterGetCurrentProcessLevel\n");
351  // returns: 0: not supported,
352  // 1: currently in user thread (gui)
353  // 2: currently in audio thread (where process is called)
354  // 3: currently in 'sequencer' thread (midi, timer etc)
355  // 4: currently offline processing and thus in user thread
356  // other: not defined, but probably pre-empting user thread.
357  return 0;
358 
360  SHOW_CALLBACK ("amc: audioMasterGetAutomationState\n");
361  // returns 0: not supported, 1: off, 2:read, 3:write, 4:read/write
362  // offline
363  return 0;
364 
366  SHOW_CALLBACK ("amc: audioMasterOfflineStart\n");
367  return 0;
368 
370  SHOW_CALLBACK ("amc: audioMasterOfflineRead\n");
371  // ptr points to offline structure, see below. return 0: error, 1 ok
372  return 0;
373 
375  SHOW_CALLBACK ("amc: audioMasterOfflineWrite\n");
376  // same as read
377  return 0;
378 
380  SHOW_CALLBACK ("amc: audioMasterOfflineGetCurrentPass\n");
381  return 0;
382 
384  SHOW_CALLBACK ("amc: audioMasterOfflineGetCurrentMetaPass\n");
385  return 0;
386 
388  SHOW_CALLBACK ("amc: audioMasterSetOutputSampleRate\n");
389  // for variable i/o, sample rate in <opt>
390  return 0;
391 
393  SHOW_CALLBACK ("amc: audioMasterGetSpeakerArrangement\n");
394  // (long)input in <value>, output in <ptr>
395  return 0;
396 
398  SHOW_CALLBACK ("amc: audioMasterGetVendorString\n");
399  // fills <ptr> with a string identifying the vendor (max 64 char)
400  strcpy ((char*) ptr, "Linux Audio Systems");
401  return 0;
402 
404  SHOW_CALLBACK ("amc: audioMasterGetProductString\n");
405  // fills <ptr> with a string with product name (max 64 char)
406  strcpy ((char*) ptr, PROGRAM_NAME);
407  return 0;
408 
410  SHOW_CALLBACK ("amc: audioMasterGetVendorVersion\n");
411  // returns vendor-specific version
412  return 900;
413 
415  SHOW_CALLBACK ("amc: audioMasterVendorSpecific\n");
416  // no definition, vendor specific handling
417  return 0;
418 
419  case audioMasterSetIcon:
420  SHOW_CALLBACK ("amc: audioMasterSetIcon\n");
421  // void* in <ptr>, format not defined yet
422  return 0;
423 
424  case audioMasterCanDo:
425  SHOW_CALLBACK ("amc: audioMasterCanDo\n");
426  // string in ptr, (const char*)ptr
427  for (int i = 0; i < vst_can_do_string_count; i++) {
428  if (! strcmp(vst_can_do_strings[i], (const char*)ptr)) {
429  return 1;
430  }
431  }
432  return 0;
433 
435  SHOW_CALLBACK ("amc: audioMasterGetLanguage\n");
436  // see enum
437  return 0;
438 
440  SHOW_CALLBACK ("amc: audioMasterOpenWindow\n");
441  // returns platform specific ptr
442  return 0;
443 
445  SHOW_CALLBACK ("amc: audioMasterCloseWindow\n");
446  // close window, platform specific handle in <ptr>
447  return 0;
448 
450  SHOW_CALLBACK ("amc: audioMasterGetDirectory\n");
451  // get plug directory, FSSpec on MAC, else char*
452  return 0;
453 
455  SHOW_CALLBACK ("amc: audioMasterUpdateDisplay\n");
456  // something has changed, update 'multi-fx' display
457  if (effect) {
458  effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f);
459  }
460  return 0;
461 
463  SHOW_CALLBACK ("amc: audioMasterBeginEdit\n");
464  // begin of automation session (when mouse down), parameter index in <index>
465  return 0;
466 
467  case audioMasterEndEdit:
468  SHOW_CALLBACK ("amc: audioMasterEndEdit\n");
469  // end of automation session (when mouse up), parameter index in <index>
470  return 0;
471 
473  SHOW_CALLBACK ("amc: audioMasterOpenFileSelector\n");
474  // open a fileselector window with VstFileSelect* in <ptr>
475  return 0;
476 
477  default:
478  SHOW_CALLBACK ("VST master dispatcher: undefed: %d\n", opcode);
479  break;
480  }
481 
482  return 0;
483 }
484 
#define audioMasterGetDirectory
Definition: aeffectx.h:75
double timecode_frames_per_second() const
Definition: session_time.cc:55
#define audioMasterCanDo
Definition: aeffectx.h:71
void set_parameter(uint32_t port, float val)
Definition: vst_plugin.cc:102
#define audioMasterGetSpeakerArrangement
Definition: aeffectx.h:65
#define DEBUG_THREAD_SELF
Definition: debug.h:63
#define audioMasterGetProductString
Definition: aeffectx.h:67
#define audioMasterIOChanged
Definition: aeffectx.h:46
#define audioMasterPinConnected
Definition: aeffectx.h:37
#define audioMasterOpenFileSelector
Definition: aeffectx.h:79
static int debug_callbacks
Definition: session_vst.cc:40
double transport_speed() const
Definition: session.h:590
static const int vst_can_do_string_count
Definition: session.h:839
#define audioMasterGetNumAutomatableParameters
Definition: aeffectx.h:44
#define SHOW_CALLBACK
Definition: session_vst.cc:43
bool get_play_loop() const
Definition: session.h:342
#define audioMasterVersion
Definition: aeffectx.h:34
#define audioMasterAutomate
Definition: aeffectx.h:33
#define audioMasterTempoAt
Definition: aeffectx.h:43
TempoMap & tempo_map()
Definition: session.h:596
#define kVstSmpteValid
Definition: aeffectx.h:146
tuple f
Definition: signals.py:35
intptr_t(* dispatcher)(struct _AEffect *, int, int, intptr_t, void *, float)
Definition: aeffectx.h:270
int32_t flags
Definition: aeffectx.h:325
#define audioMasterProcessEvents
Definition: aeffectx.h:41
#define audioMasterVendorSpecific
Definition: aeffectx.h:69
#define audioMasterGetAutomationState
Definition: aeffectx.h:57
#define effEditIdle
Definition: aeffectx.h:101
static AudioEngine * instance()
Definition: audioengine.h:196
framecnt_t frame_rate() const
Definition: session.h:365
#define kVstMidiType
Definition: aeffectx.h:134
#define audioMasterGetVendorVersion
Definition: aeffectx.h:68
#define audioMasterOfflineGetCurrentPass
Definition: aeffectx.h:61
#define audioMasterGetVendorString
Definition: aeffectx.h:66
int wantIdle
Definition: vst_types.h:97
double ppqPos
Definition: aeffectx.h:315
#define audioMasterOfflineGetCurrentMetaPass
Definition: aeffectx.h:62
framecnt_t sample_rate() const
Definition: audioengine.cc:974
#define audioMasterSetTime
Definition: aeffectx.h:42
MidiBuffer * midi_buffer() const
Definition: vst_plugin.h:76
#define audioMasterIdle
Definition: aeffectx.h:36
#define audioMasterGetParameterQuantization
Definition: aeffectx.h:45
#define audioMasterNeedIdle
Definition: aeffectx.h:47
bool timecode_drop_frames() const
Definition: session_time.cc:61
#define X_(Text)
Definition: i18n.h:13
const char * name() const
Definition: vst_plugin.cc:615
#define audioMasterWillReplaceOrAccumulate
Definition: aeffectx.h:55
VSTState * state() const
Definition: vst_plugin.h:75
#define audioMasterOfflineWrite
Definition: aeffectx.h:60
#define audioMasterWantMidi
Definition: aeffectx.h:39
VstEvent * events[]
Definition: aeffectx.h:193
static intptr_t vst_callback(AEffect *effect, int32_t opcode, int32_t index, intptr_t value, void *ptr, float opt)
Definition: session_vst.cc:64
#define audioMasterSetOutputSampleRate
Definition: aeffectx.h:63
framepos_t transport_frame() const
Definition: session.h:551
Definition: amp.h:29
#define kVstPpqPosValid
Definition: aeffectx.h:141
#define audioMasterGetCurrentProcessLevel
Definition: aeffectx.h:56
double samplePos
Definition: aeffectx.h:312
#define audioMasterBeginEdit
Definition: aeffectx.h:77
int intptr_t
Definition: types.h:46
int64_t framepos_t
Definition: types.h:66
#define audioMasterGetNextPlug
Definition: aeffectx.h:54
#define audioMasterGetBlockSize
Definition: aeffectx.h:50
#define audioMasterGetSampleRate
Definition: aeffectx.h:49
void bbt_time_rt(framepos_t when, Timecode::BBT_Time &)
Definition: tempo.cc:1186
PluginInfoPtr get_info() const
Definition: plugin.h:225
double beats_per_minute() const
Definition: tempo.h:53
ChanCount n_inputs
Definition: plugin.h:63
#define audioMasterUpdateDisplay
Definition: aeffectx.h:76
#define audioMasterGetLanguage
Definition: aeffectx.h:72
static int vst_current_loading_id
Definition: session.h:837
#define kVstTransportPlaying
Definition: aeffectx.h:138
pframes_t get_block_size() const
Definition: session.h:393
char dump[sizeof(VstMidiEvent)]
Definition: aeffectx.h:180
void set_midi(uint32_t m)
Definition: chan_count.h:67
double sampleRate
Definition: aeffectx.h:313
bool push_back(const Evoral::MIDIEvent< TimeType > &event)
Definition: midi_buffer.cc:136
#define audioMasterGetOutputLatency
Definition: aeffectx.h:52
#define kVstTimeSigValid
Definition: aeffectx.h:145
#define kVstTempoValid
Definition: aeffectx.h:142
int32_t timeSigDenominator
Definition: aeffectx.h:321
#define audioMasterGetTime
Definition: aeffectx.h:40
TempoMetric metric_at(Timecode::BBT_Time bbt) const
Definition: tempo.cc:1141
#define audioMasterGetInputLatency
Definition: aeffectx.h:51
double tempo
Definition: aeffectx.h:316
static const char * vst_can_do_strings[]
Definition: session.h:838
int deltaFrames
Definition: aeffectx.h:156
char midiData[4]
Definition: aeffectx.h:164
#define audioMasterCurrentId
Definition: aeffectx.h:35
void timecode_time(Timecode::Time &)
#define audioMasterCloseWindow
Definition: aeffectx.h:74
#define audioMasterSetIcon
Definition: aeffectx.h:70
#define audioMasterGetPreviousPlug
Definition: aeffectx.h:53
int numEvents
Definition: aeffectx.h:189
#define audioMasterOfflineStart
Definition: aeffectx.h:58
#define kVstBarsValid
Definition: aeffectx.h:143
#define audioMasterOfflineRead
Definition: aeffectx.h:59
ARDOUR::Session & session() const
Definition: plugin.h:229
const Tempo & tempo_at(framepos_t) const
Definition: tempo.cc:1617
double barStartPos
Definition: aeffectx.h:317
#define audioMasterEndEdit
Definition: aeffectx.h:78
#define audioMasterSizeWindow
Definition: aeffectx.h:48
void * user
Definition: aeffectx.h:297
#define audioMasterOpenWindow
Definition: aeffectx.h:73
int32_t timeSigNumerator
Definition: aeffectx.h:320
int32_t smpteOffset
Definition: aeffectx.h:322
int32_t smpteFrameRate
Definition: aeffectx.h:323