1#!/usr/local/bin/python3.8
2# -*- coding: utf-8 -*-
3
4# Carla Backend code
5# Copyright (C) 2011-2021 Filipe Coelho <falktx@falktx.com>
6#
7# This program is free software; you can redistribute it and/or
8# modify it under the terms of the GNU General Public License as
9# published by the Free Software Foundation; either version 2 of
10# the License, or any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# For a full copy of the GNU General Public License see the doc/GPL.txt file.
18
19# ---------------------------------------------------------------------------------------------------------------------
20# Imports (Global)
21
22from abc import abstractmethod
23from platform import architecture
24from struct import pack
25from sys import platform, maxsize
26
27# ---------------------------------------------------------------------------------------------------------------------
28# Imports (ctypes)
29
30from ctypes import (
31    c_bool, c_char_p, c_double, c_float, c_int, c_long, c_longdouble, c_longlong, c_ubyte, c_uint, c_void_p,
32    c_int8, c_int16, c_int32, c_int64, c_uint8, c_uint16, c_uint32, c_uint64,
33    cast, Structure,
34    CDLL, CFUNCTYPE, RTLD_GLOBAL, RTLD_LOCAL, POINTER
35)
36
37# ---------------------------------------------------------------------------------------------------------------------
38# 64bit check
39
40kIs64bit = bool(architecture()[0] == "64bit" and maxsize > 2**32)
41
42# ---------------------------------------------------------------------------------------------------------------------
43# Define custom types
44
45c_enum = c_int
46c_uintptr = c_uint64 if kIs64bit else c_uint32
47
48# ---------------------------------------------------------------------------------------------------------------------
49# Set Platform
50
51if platform == "darwin":
52    HAIKU   = False
53    LINUX   = False
54    MACOS   = True
55    WINDOWS = False
56elif "haiku" in platform:
57    HAIKU   = True
58    LINUX   = False
59    MACOS   = False
60    WINDOWS = False
61elif "linux" in platform:
62    HAIKU   = False
63    LINUX   = True
64    MACOS   = False
65    WINDOWS = False
66elif platform in ("win32", "win64", "cygwin"):
67    HAIKU   = False
68    LINUX   = False
69    MACOS   = False
70    WINDOWS = True
71else:
72    HAIKU   = False
73    LINUX   = False
74    MACOS   = False
75    WINDOWS = False
76
77# ---------------------------------------------------------------------------------------------------------------------
78# Convert a ctypes c_char_p into a python string
79
80def charPtrToString(charPtr):
81    if not charPtr:
82        return ""
83    if isinstance(charPtr, str):
84        return charPtr
85    return charPtr.decode("utf-8", errors="ignore")
86
87# ---------------------------------------------------------------------------------------------------------------------
88# Convert a ctypes POINTER(c_char_p) into a python string list
89
90def charPtrPtrToStringList(charPtrPtr):
91    if not charPtrPtr:
92        return []
93
94    i       = 0
95    charPtr = charPtrPtr[0]
96    strList = []
97
98    while charPtr:
99        strList.append(charPtr.decode("utf-8", errors="ignore"))
100
101        i += 1
102        charPtr = charPtrPtr[i]
103
104    return strList
105
106# ---------------------------------------------------------------------------------------------------------------------
107# Convert a ctypes POINTER(c_<num>) into a python number list
108
109def numPtrToList(numPtr):
110    if not numPtr:
111        return []
112
113    i       = 0
114    num     = numPtr[0] #.value
115    numList = []
116
117    while num not in (0, 0.0):
118        numList.append(num)
119
120        i += 1
121        num = numPtr[i] #.value
122
123    return numList
124
125# ---------------------------------------------------------------------------------------------------------------------
126# Convert a ctypes value into a python one
127
128c_int_types    = (c_int, c_int8, c_int16, c_int32, c_int64,
129                  c_uint, c_uint8, c_uint16, c_uint32, c_uint64, c_long, c_longlong)
130c_float_types  = (c_float, c_double, c_longdouble)
131c_intp_types   = tuple(POINTER(i) for i in c_int_types)
132c_floatp_types = tuple(POINTER(i) for i in c_float_types)
133
134def toPythonType(value, attr):
135    if isinstance(value, (bool, int, float)):
136        return value
137    if isinstance(value, bytes):
138        return charPtrToString(value)
139    # pylint: disable=consider-merging-isinstance
140    if isinstance(value, c_intp_types) or isinstance(value, c_floatp_types):
141        return numPtrToList(value)
142    # pylint: enable=consider-merging-isinstance
143    if isinstance(value, POINTER(c_char_p)):
144        return charPtrPtrToStringList(value)
145    print("..............", attr, ".....................", value, ":", type(value))
146    return value
147
148# ---------------------------------------------------------------------------------------------------------------------
149# Convert a ctypes struct into a python dict
150
151def structToDict(struct):
152    # pylint: disable=protected-access
153    return dict((attr, toPythonType(getattr(struct, attr), attr)) for attr, value in struct._fields_)
154    # pylint: enable=protected-access
155
156# ---------------------------------------------------------------------------------------------------------------------
157# Carla Backend API (base definitions)
158
159# Maximum default number of loadable plugins.
160MAX_DEFAULT_PLUGINS = 512
161
162# Maximum number of loadable plugins in rack mode.
163MAX_RACK_PLUGINS = 64
164
165# Maximum number of loadable plugins in patchbay mode.
166MAX_PATCHBAY_PLUGINS = 255
167
168# Maximum default number of parameters allowed.
169# @see ENGINE_OPTION_MAX_PARAMETERS
170MAX_DEFAULT_PARAMETERS = 200
171
172# The "plugin Id" for the global Carla instance.
173# Currently only used for audio peaks.
174MAIN_CARLA_PLUGIN_ID = 0xFFFF
175
176# ---------------------------------------------------------------------------------------------------------------------
177# Engine Driver Device Hints
178# Various engine driver device hints.
179# @see carla_get_engine_driver_device_info()
180
181# Engine driver device has custom control-panel.
182ENGINE_DRIVER_DEVICE_HAS_CONTROL_PANEL = 0x1
183
184# Engine driver device can use a triple-buffer (3 number of periods instead of the usual 2).
185# @see ENGINE_OPTION_AUDIO_NUM_PERIODS
186ENGINE_DRIVER_DEVICE_CAN_TRIPLE_BUFFER = 0x2
187
188# Engine driver device can change buffer-size on the fly.
189# @see ENGINE_OPTION_AUDIO_BUFFER_SIZE
190ENGINE_DRIVER_DEVICE_VARIABLE_BUFFER_SIZE = 0x4
191
192# Engine driver device can change sample-rate on the fly.
193# @see ENGINE_OPTION_AUDIO_SAMPLE_RATE
194ENGINE_DRIVER_DEVICE_VARIABLE_SAMPLE_RATE = 0x8
195
196# ---------------------------------------------------------------------------------------------------------------------
197# Plugin Hints
198# Various plugin hints.
199# @see carla_get_plugin_info()
200
201# Plugin is a bridge.
202# This hint is required because "bridge" itself is not a plugin type.
203PLUGIN_IS_BRIDGE = 0x001
204
205# Plugin is hard real-time safe.
206PLUGIN_IS_RTSAFE = 0x002
207
208# Plugin is a synth (produces sound).
209PLUGIN_IS_SYNTH = 0x004
210
211# Plugin has its own custom UI.
212# @see carla_show_custom_ui()
213PLUGIN_HAS_CUSTOM_UI = 0x008
214
215# Plugin can use internal Dry/Wet control.
216PLUGIN_CAN_DRYWET = 0x010
217
218# Plugin can use internal Volume control.
219PLUGIN_CAN_VOLUME = 0x020
220
221# Plugin can use internal (Stereo) Balance controls.
222PLUGIN_CAN_BALANCE = 0x040
223
224# Plugin can use internal (Mono) Panning control.
225PLUGIN_CAN_PANNING = 0x080
226
227# Plugin needs a constant, fixed-size audio buffer.
228PLUGIN_NEEDS_FIXED_BUFFERS = 0x100
229
230# Plugin needs to receive all UI events in the main thread.
231PLUGIN_NEEDS_UI_MAIN_THREAD = 0x200
232
233# Plugin uses 1 program per MIDI channel.
234# @note: Only used in some internal plugins and sf2 files.
235PLUGIN_USES_MULTI_PROGS = 0x400
236
237# Plugin can make use of inline display API.
238PLUGIN_HAS_INLINE_DISPLAY = 0x800
239
240# ---------------------------------------------------------------------------------------------------------------------
241# Plugin Options
242# Various plugin options.
243# @see carla_get_plugin_info() and carla_set_option()
244
245# Use constant/fixed-size audio buffers.
246PLUGIN_OPTION_FIXED_BUFFERS = 0x001
247
248# Force mono plugin as stereo.
249PLUGIN_OPTION_FORCE_STEREO = 0x002
250
251# Map MIDI programs to plugin programs.
252PLUGIN_OPTION_MAP_PROGRAM_CHANGES = 0x004
253
254# Use chunks to save and restore data instead of parameter values.
255PLUGIN_OPTION_USE_CHUNKS = 0x008
256
257# Send MIDI control change events.
258PLUGIN_OPTION_SEND_CONTROL_CHANGES = 0x010
259
260# Send MIDI channel pressure events.
261PLUGIN_OPTION_SEND_CHANNEL_PRESSURE = 0x020
262
263# Send MIDI note after-touch events.
264PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH = 0x040
265
266# Send MIDI pitch-bend events.
267PLUGIN_OPTION_SEND_PITCHBEND = 0x080
268
269# Send MIDI all-sounds/notes-off events, single note-offs otherwise.
270PLUGIN_OPTION_SEND_ALL_SOUND_OFF = 0x100
271
272# Send MIDI bank/program changes.
273# @note: This option conflicts with PLUGIN_OPTION_MAP_PROGRAM_CHANGES and cannot be used at the same time.
274PLUGIN_OPTION_SEND_PROGRAM_CHANGES = 0x200
275
276# SSkip sending MIDI note events.
277# This if off-by-default as a way to keep backwards compatibility.
278# We always want notes enabled by default, not the contrary.
279PLUGIN_OPTION_SKIP_SENDING_NOTES = 0x400
280
281# Special flag to indicate that plugin options are not yet set.
282# This flag exists because 0x0 as an option value is a valid one, so we need something else to indicate "null-ness".
283PLUGIN_OPTIONS_NULL = 0x10000
284
285# ---------------------------------------------------------------------------------------------------------------------
286# Parameter Hints
287# Various parameter hints.
288# @see CarlaPlugin::getParameterData() and carla_get_parameter_data()
289
290# Parameter value is boolean.
291PARAMETER_IS_BOOLEAN = 0x001
292
293# Parameter value is integer.
294PARAMETER_IS_INTEGER = 0x002
295
296# Parameter value is logarithmic.
297PARAMETER_IS_LOGARITHMIC = 0x004
298
299# Parameter is enabled.
300# It can be viewed, changed and stored.
301PARAMETER_IS_ENABLED = 0x010
302
303# Parameter is automable (real-time safe).
304PARAMETER_IS_AUTOMABLE = 0x020
305
306# Parameter is read-only.
307# It cannot be changed.
308PARAMETER_IS_READ_ONLY = 0x040
309
310# Parameter needs sample rate to work.
311# Value and ranges are multiplied by sample rate on usage and divided by sample rate on save.
312PARAMETER_USES_SAMPLERATE = 0x100
313
314# Parameter uses scale points to define internal values in a meaningful way.
315PARAMETER_USES_SCALEPOINTS = 0x200
316
317# Parameter uses custom text for displaying its value.
318# @see carla_get_parameter_text()
319PARAMETER_USES_CUSTOM_TEXT = 0x400
320
321# Parameter can be turned into a CV control.
322PARAMETER_CAN_BE_CV_CONTROLLED = 0x800
323
324# Parameter should not be saved as part of the project/session.
325# @note only valid for parameter inputs.
326PARAMETER_IS_NOT_SAVED = 0x1000
327
328# ---------------------------------------------------------------------------------------------------------------------
329# Mapped Parameter Flags
330# Various flags for parameter mappings.
331# @see ParameterData::mappedFlags
332
333PARAMETER_MAPPING_MIDI_DELTA = 0x001
334
335# ---------------------------------------------------------------------------------------------------------------------
336# Patchbay Port Hints
337# Various patchbay port hints.
338
339# Patchbay port is input.
340# When this hint is not set, port is assumed to be output.
341PATCHBAY_PORT_IS_INPUT = 0x01
342
343# Patchbay port is of Audio type.
344PATCHBAY_PORT_TYPE_AUDIO = 0x02
345
346# Patchbay port is of CV type (Control Voltage).
347PATCHBAY_PORT_TYPE_CV = 0x04
348
349# Patchbay port is of MIDI type.
350PATCHBAY_PORT_TYPE_MIDI = 0x08
351
352# Patchbay port is of OSC type.
353PATCHBAY_PORT_TYPE_OSC = 0x10
354
355# ---------------------------------------------------------------------------------------------------------------------
356# Patchbay Port Group Hints
357# Various patchbay port group hints.
358
359# Indicates that this group should be considered the "main" input.
360PATCHBAY_PORT_GROUP_MAIN_INPUT = 0x01
361
362# Indicates that this group should be considered the "main" output.
363PATCHBAY_PORT_GROUP_MAIN_OUTPUT = 0x02
364
365# A stereo port group, where the 1st port is left and the 2nd is right.
366PATCHBAY_PORT_GROUP_STEREO = 0x04
367
368# A mid-side stereo group, where the 1st port is center and the 2nd is side.
369PATCHBAY_PORT_GROUP_MID_SIDE = 0x08
370
371# ---------------------------------------------------------------------------------------------------------------------
372# Custom Data Types
373# These types define how the value in the CustomData struct is stored.
374# @see CustomData.type
375
376# Boolean string type URI.
377# Only "true" and "false" are valid values.
378CUSTOM_DATA_TYPE_BOOLEAN = "http://kxstudio.sf.net/ns/carla/boolean"
379
380# Chunk type URI.
381CUSTOM_DATA_TYPE_CHUNK = "http://kxstudio.sf.net/ns/carla/chunk"
382
383# Property type URI.
384CUSTOM_DATA_TYPE_PROPERTY = "http://kxstudio.sf.net/ns/carla/property"
385
386# String type URI.
387CUSTOM_DATA_TYPE_STRING = "http://kxstudio.sf.net/ns/carla/string"
388
389# ---------------------------------------------------------------------------------------------------------------------
390# Custom Data Keys
391# Pre-defined keys used internally in Carla.
392# @see CustomData.key
393
394# Plugin options key.
395CUSTOM_DATA_KEY_PLUGIN_OPTIONS = "CarlaPluginOptions"
396
397# UI position key.
398CUSTOM_DATA_KEY_UI_POSITION = "CarlaUiPosition"
399
400# UI size key.
401CUSTOM_DATA_KEY_UI_SIZE = "CarlaUiSize"
402
403# UI visible key.
404CUSTOM_DATA_KEY_UI_VISIBLE = "CarlaUiVisible"
405
406# ---------------------------------------------------------------------------------------------------------------------
407# Binary Type
408# The binary type of a plugin.
409
410# Null binary type.
411BINARY_NONE = 0
412
413# POSIX 32bit binary.
414BINARY_POSIX32 = 1
415
416# POSIX 64bit binary.
417BINARY_POSIX64 = 2
418
419# Windows 32bit binary.
420BINARY_WIN32 = 3
421
422# Windows 64bit binary.
423BINARY_WIN64 = 4
424
425# Other binary type.
426BINARY_OTHER = 5
427
428# ---------------------------------------------------------------------------------------------------------------------
429# File Type
430# File type.
431
432# Null file type.
433FILE_NONE = 0
434
435# Audio file.
436FILE_AUDIO = 1
437
438# MIDI file.
439FILE_MIDI = 2
440
441# ---------------------------------------------------------------------------------------------------------------------
442# Plugin Type
443# Plugin type.
444# Some files are handled as if they were plugins.
445
446# Null plugin type.
447PLUGIN_NONE = 0
448
449# Internal plugin.
450PLUGIN_INTERNAL = 1
451
452# LADSPA plugin.
453PLUGIN_LADSPA = 2
454
455# DSSI plugin.
456PLUGIN_DSSI = 3
457
458# LV2 plugin.
459PLUGIN_LV2 = 4
460
461# VST2 plugin.
462PLUGIN_VST2 = 5
463
464# VST3 plugin.
465# @note Windows and MacOS only
466PLUGIN_VST3 = 6
467
468# AU plugin.
469# @note MacOS only
470PLUGIN_AU = 7
471
472# DLS file.
473PLUGIN_DLS = 8
474
475# GIG file.
476PLUGIN_GIG = 9
477
478# SF2/3 file (SoundFont).
479PLUGIN_SF2 = 10
480
481# SFZ file.
482PLUGIN_SFZ = 11
483
484# JACK application.
485PLUGIN_JACK = 12
486
487# ---------------------------------------------------------------------------------------------------------------------
488# Plugin Category
489# Plugin category, which describes the functionality of a plugin.
490
491# Null plugin category.
492PLUGIN_CATEGORY_NONE = 0
493
494# A synthesizer or generator.
495PLUGIN_CATEGORY_SYNTH = 1
496
497# A delay or reverb.
498PLUGIN_CATEGORY_DELAY = 2
499
500# An equalizer.
501PLUGIN_CATEGORY_EQ = 3
502
503# A filter.
504PLUGIN_CATEGORY_FILTER = 4
505
506# A distortion plugin.
507PLUGIN_CATEGORY_DISTORTION = 5
508
509# A 'dynamic' plugin (amplifier, compressor, gate, etc).
510PLUGIN_CATEGORY_DYNAMICS = 6
511
512# A 'modulator' plugin (chorus, flanger, phaser, etc).
513PLUGIN_CATEGORY_MODULATOR = 7
514
515# An 'utility' plugin (analyzer, converter, mixer, etc).
516PLUGIN_CATEGORY_UTILITY = 8
517
518# Miscellaneous plugin (used to check if the plugin has a category).
519PLUGIN_CATEGORY_OTHER = 9
520
521# ---------------------------------------------------------------------------------------------------------------------
522# Parameter Type
523# Plugin parameter type.
524
525# Null parameter type.
526PARAMETER_UNKNOWN = 0
527
528# Input parameter.
529PARAMETER_INPUT = 1
530
531# Output parameter.
532PARAMETER_OUTPUT = 2
533
534# ---------------------------------------------------------------------------------------------------------------------
535# Internal Parameter Index
536# Special parameters used internally in Carla.
537# Plugins do not know about their existence.
538
539# Null parameter.
540PARAMETER_NULL = -1
541
542# Active parameter, boolean type.
543# Default is 'false'.
544PARAMETER_ACTIVE = -2
545
546# Dry/Wet parameter.
547# Range 0.0...1.0; default is 1.0.
548PARAMETER_DRYWET = -3
549
550# Volume parameter.
551# Range 0.0...1.27; default is 1.0.
552PARAMETER_VOLUME = -4
553
554# Stereo Balance-Left parameter.
555# Range -1.0...1.0; default is -1.0.
556PARAMETER_BALANCE_LEFT = -5
557
558# Stereo Balance-Right parameter.
559# Range -1.0...1.0; default is 1.0.
560PARAMETER_BALANCE_RIGHT = -6
561
562# Mono Panning parameter.
563# Range -1.0...1.0; default is 0.0.
564PARAMETER_PANNING = -7
565
566# MIDI Control channel, integer type.
567# Range -1...15 (-1 = off).
568PARAMETER_CTRL_CHANNEL = -8
569
570# Max value, defined only for convenience.
571PARAMETER_MAX = -9
572
573# ---------------------------------------------------------------------------------------------------------------------
574# Special Mapped Control Index
575
576# Specially designated mapped control indexes.
577# Values between 0 and 119 (0x77) are reserved for MIDI CC, which uses direct values.
578# @see ParameterData::mappedControlIndex
579
580# Unused control index, meaning no mapping is enabled.
581CONTROL_INDEX_NONE = -1
582
583# CV control index, meaning the parameter is exposed as CV port.
584CONTROL_INDEX_CV = 130
585
586# Special value to indicate MIDI pitchbend.
587CONTROL_INDEX_MIDI_PITCHBEND = 131
588
589# Special value to indicate MIDI learn.
590CONTROL_INDEX_MIDI_LEARN = 132
591
592# Special value to indicate MIDI pitchbend.
593CONTROL_INDEX_MAX_ALLOWED = CONTROL_INDEX_MIDI_LEARN
594
595# ---------------------------------------------------------------------------------------------------------------------
596# Engine Callback Opcode
597# Engine callback opcodes.
598# Front-ends must never block indefinitely during a callback.
599# @see EngineCallbackFunc and carla_set_engine_callback()
600
601# Debug.
602# This opcode is undefined and used only for testing purposes.
603ENGINE_CALLBACK_DEBUG = 0
604
605# A plugin has been added.
606# @a pluginId Plugin Id
607# @a valueStr Plugin name
608ENGINE_CALLBACK_PLUGIN_ADDED = 1
609
610# A plugin has been removed.
611# @a pluginId Plugin Id
612ENGINE_CALLBACK_PLUGIN_REMOVED = 2
613
614# A plugin has been renamed.
615# @a pluginId Plugin Id
616# @a valueStr New plugin name
617ENGINE_CALLBACK_PLUGIN_RENAMED = 3
618
619# A plugin has become unavailable.
620# @a pluginId Plugin Id
621# @a valueStr Related error string
622ENGINE_CALLBACK_PLUGIN_UNAVAILABLE = 4
623
624# A parameter value has changed.
625# @a pluginId Plugin Id
626# @a value1   Parameter index
627# @a valuef   New parameter value
628ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED = 5
629
630# A parameter default has changed.
631# @a pluginId Plugin Id
632# @a value1   Parameter index
633# @a valuef   New default value
634ENGINE_CALLBACK_PARAMETER_DEFAULT_CHANGED = 6
635
636# A parameter's mapped control index has changed.
637# @a pluginId Plugin Id
638# @a value1   Parameter index
639# @a value2   New control index
640ENGINE_CALLBACK_PARAMETER_MAPPED_CONTROL_INDEX_CHANGED = 7
641
642# A parameter's MIDI channel has changed.
643# @a pluginId Plugin Id
644# @a value1   Parameter index
645# @a value2   New MIDI channel
646ENGINE_CALLBACK_PARAMETER_MIDI_CHANNEL_CHANGED = 8
647
648# A plugin option has changed.
649# @a pluginId Plugin Id
650# @a value1   Option
651# @a value2   New on/off state (1 for on, 0 for off)
652# @see PluginOptions
653ENGINE_CALLBACK_OPTION_CHANGED = 9
654
655# The current program of a plugin has changed.
656# @a pluginId Plugin Id
657# @a value1   New program index
658ENGINE_CALLBACK_PROGRAM_CHANGED = 10
659
660# The current MIDI program of a plugin has changed.
661# @a pluginId Plugin Id
662# @a value1   New MIDI program index
663ENGINE_CALLBACK_MIDI_PROGRAM_CHANGED = 11
664
665# A plugin's custom UI state has changed.
666# @a pluginId Plugin Id
667# @a value1   New state, as follows:
668#                  0: UI is now hidden
669#                  1: UI is now visible
670#                 -1: UI has crashed and should not be shown again
671ENGINE_CALLBACK_UI_STATE_CHANGED = 12
672
673# A note has been pressed.
674# @a pluginId Plugin Id
675# @a value1   Channel
676# @a value2   Note
677# @a value3   Velocity
678ENGINE_CALLBACK_NOTE_ON = 13
679
680# A note has been released.
681# @a pluginId Plugin Id
682# @a value1   Channel
683# @a value2   Note
684ENGINE_CALLBACK_NOTE_OFF = 14
685
686# A plugin needs update.
687# @a pluginId Plugin Id
688ENGINE_CALLBACK_UPDATE = 15
689
690# A plugin's data/information has changed.
691# @a pluginId Plugin Id
692ENGINE_CALLBACK_RELOAD_INFO = 16
693
694# A plugin's parameters have changed.
695# @a pluginId Plugin Id
696ENGINE_CALLBACK_RELOAD_PARAMETERS = 17
697
698# A plugin's programs have changed.
699# @a pluginId Plugin Id
700ENGINE_CALLBACK_RELOAD_PROGRAMS = 18
701
702# A plugin state has changed.
703# @a pluginId Plugin Id
704ENGINE_CALLBACK_RELOAD_ALL = 19
705
706# A patchbay client has been added.
707# @a pluginId Client Id
708# @a value1   Client icon
709# @a value2   Plugin Id (-1 if not a plugin)
710# @a valueStr Client name
711# @see PatchbayIcon
712ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED = 20
713
714# A patchbay client has been removed.
715# @a pluginId Client Id
716ENGINE_CALLBACK_PATCHBAY_CLIENT_REMOVED = 21
717
718# A patchbay client has been renamed.
719# @a pluginId Client Id
720# @a valueStr New client name
721ENGINE_CALLBACK_PATCHBAY_CLIENT_RENAMED = 22
722
723# A patchbay client data has changed.
724# @a pluginId Client Id
725# @a value1   New icon
726# @a value2   New plugin Id (-1 if not a plugin)
727# @see PatchbayIcon
728ENGINE_CALLBACK_PATCHBAY_CLIENT_DATA_CHANGED = 23
729
730# A patchbay port has been added.
731# @a pluginId Client Id
732# @a value1   Port Id
733# @a value2   Port hints
734# @a value3   Port group Id (0 for none)
735# @a valueStr Port name
736# @see PatchbayPortHints
737ENGINE_CALLBACK_PATCHBAY_PORT_ADDED = 24
738
739# A patchbay port has been removed.
740# @a pluginId Client Id
741# @a value1   Port Id
742ENGINE_CALLBACK_PATCHBAY_PORT_REMOVED = 25
743
744# A patchbay port has changed (like the name or group Id).
745# @a pluginId Client Id
746# @a value1   Port Id
747# @a value2   Port hints
748# @a value3   Port group Id (0 for none)
749# @a valueStr New port name
750ENGINE_CALLBACK_PATCHBAY_PORT_CHANGED = 26
751
752# A patchbay connection has been added.
753# @a pluginId Connection Id
754# @a valueStr Out group, port plus in group and port, in "og:op:ig:ip" syntax.
755ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED = 27
756
757# A patchbay connection has been removed.
758# @a pluginId Connection Id
759ENGINE_CALLBACK_PATCHBAY_CONNECTION_REMOVED = 28
760
761# Engine started.
762# @a pluginId How many plugins are known to be running
763# @a value1   Process mode
764# @a value2   Transport mode
765# @a value3   Buffer size
766# @a valuef   Sample rate
767# @a valuestr Engine driver
768# @see EngineProcessMode
769# @see EngineTransportMode
770ENGINE_CALLBACK_ENGINE_STARTED = 29
771
772# Engine stopped.
773ENGINE_CALLBACK_ENGINE_STOPPED = 30
774
775# Engine process mode has changed.
776# @a value1 New process mode
777# @see EngineProcessMode
778ENGINE_CALLBACK_PROCESS_MODE_CHANGED = 31
779
780# Engine transport mode has changed.
781# @a value1   New transport mode
782# @a valueStr New transport features enabled
783# @see EngineTransportMode
784ENGINE_CALLBACK_TRANSPORT_MODE_CHANGED = 32
785
786# Engine buffer-size changed.
787# @a value1 New buffer size
788ENGINE_CALLBACK_BUFFER_SIZE_CHANGED = 33
789
790# Engine sample-rate changed.
791# @a valuef New sample rate
792ENGINE_CALLBACK_SAMPLE_RATE_CHANGED = 34
793
794# A cancelable action has been started or stopped.
795# @a pluginId Plugin Id the action relates to, -1 for none
796# @a value1   1 for action started, 0 for stopped
797# @a valueStr Action name
798ENGINE_CALLBACK_CANCELABLE_ACTION = 35
799
800# Project has finished loading.
801ENGINE_CALLBACK_PROJECT_LOAD_FINISHED = 36
802
803# NSM callback.
804# Frontend must call carla_nsm_ready() with opcode as parameter as a response
805# @a value1   NSM opcode
806# @a value2   Integer value
807# @a valueStr String value
808# @see NsmCallbackOpcode
809ENGINE_CALLBACK_NSM = 37
810
811# Idle frontend.
812# This is used by the engine during long operations that might block the frontend,
813# giving it the possibility to idle while the operation is still in place.
814ENGINE_CALLBACK_IDLE = 38
815
816# Show a message as information.
817# @a valueStr The message
818ENGINE_CALLBACK_INFO = 39
819
820# Show a message as an error.
821# @a valueStr The message
822ENGINE_CALLBACK_ERROR = 40
823
824# The engine has crashed or malfunctioned and will no longer work.
825ENGINE_CALLBACK_QUIT = 41
826
827# A plugin requested for its inline display to be redrawn.
828# @a pluginId Plugin Id to redraw
829ENGINE_CALLBACK_INLINE_DISPLAY_REDRAW = 42
830
831# A patchbay port group has been added.
832# @a pluginId Client Id
833# @a value1   Group Id (unique within this client)
834# @a value2   Group hints
835# @a valueStr Group name
836# @see PatchbayPortGroupHints
837ENGINE_CALLBACK_PATCHBAY_PORT_GROUP_ADDED = 43
838
839# A patchbay port group has been removed.
840# @a pluginId Client Id
841# @a value1   Group Id (unique within this client)
842ENGINE_CALLBACK_PATCHBAY_PORT_GROUP_REMOVED = 44
843
844# A patchbay port group has changed.
845# @a pluginId Client Id
846# @a value1   Group Id (unique within this client)
847# @a value2   Group hints
848# @a valueStr Group name
849# @see PatchbayPortGroupHints
850ENGINE_CALLBACK_PATCHBAY_PORT_GROUP_CHANGED = 45
851
852# A parameter's mapped range has changed.
853# @a pluginId Plugin Id
854# @a value1   Parameter index
855# @a valueStr New mapped range as "%f:%f" syntax
856ENGINE_CALLBACK_PARAMETER_MAPPED_RANGE_CHANGED = 46
857
858# A patchbay client position has changed.
859# @a pluginId Client Id
860# @a value1   X position 1
861# @a value2   Y position 1
862# @a value3   X position 2
863# @a valuef   Y position 2
864ENGINE_CALLBACK_PATCHBAY_CLIENT_POSITION_CHANGED = 47
865
866# ---------------------------------------------------------------------------------------------------------------------
867# NSM Callback Opcode
868# NSM callback opcodes.
869# @see ENGINE_CALLBACK_NSM
870
871# NSM is available and initialized.
872NSM_CALLBACK_INIT = 0
873
874# Error from NSM side.
875# @a valueInt Error code
876# @a valueStr Error string
877NSM_CALLBACK_ERROR = 1
878
879# Announce message.
880# @a valueInt SM Flags (WIP, to be defined)
881# @a valueStr SM Name
882NSM_CALLBACK_ANNOUNCE = 2
883
884# Open message.
885# @a valueStr Project filename
886NSM_CALLBACK_OPEN = 3
887
888# Save message.
889NSM_CALLBACK_SAVE = 4
890
891# Session-is-loaded message.
892NSM_CALLBACK_SESSION_IS_LOADED = 5
893
894# Show-optional-gui message.
895NSM_CALLBACK_SHOW_OPTIONAL_GUI = 6
896
897# Hide-optional-gui message.
898NSM_CALLBACK_HIDE_OPTIONAL_GUI = 7
899
900# Set client name id message.
901NSM_CALLBACK_SET_CLIENT_NAME_ID = 8
902
903# ---------------------------------------------------------------------------------------------------------------------
904# Engine Option
905# Engine options.
906# @see carla_set_engine_option()
907
908# Debug.
909# This option is undefined and used only for testing purposes.
910ENGINE_OPTION_DEBUG = 0
911
912# Set the engine processing mode.
913# Default is ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS on Linux and ENGINE_PROCESS_MODE_CONTINUOUS_RACK for all other OSes.
914# @see EngineProcessMode
915ENGINE_OPTION_PROCESS_MODE = 1
916
917# Set the engine transport mode.
918# Default is ENGINE_TRANSPORT_MODE_JACK on Linux and ENGINE_TRANSPORT_MODE_INTERNAL for all other OSes.
919# @see EngineTransportMode
920ENGINE_OPTION_TRANSPORT_MODE = 2
921
922# Force mono plugins as stereo, by running 2 instances at the same time.
923# Default is false, but always true when process mode is ENGINE_PROCESS_MODE_CONTINUOUS_RACK.
924# @note Not supported by all plugins
925# @see PLUGIN_OPTION_FORCE_STEREO
926ENGINE_OPTION_FORCE_STEREO = 3
927
928# Use plugin bridges whenever possible.
929# Default is no, EXPERIMENTAL.
930ENGINE_OPTION_PREFER_PLUGIN_BRIDGES = 4
931
932# Use UI bridges whenever possible, otherwise UIs will be directly handled in the main backend thread.
933# Default is yes.
934ENGINE_OPTION_PREFER_UI_BRIDGES = 5
935
936# Make custom plugin UIs always-on-top.
937# Default is yes.
938ENGINE_OPTION_UIS_ALWAYS_ON_TOP = 6
939
940# Maximum number of parameters allowed.
941# Default is MAX_DEFAULT_PARAMETERS.
942ENGINE_OPTION_MAX_PARAMETERS = 7
943
944# Reset Xrun counter after project load.
945ENGINE_OPTION_RESET_XRUNS = 8
946
947# Timeout value for how much to wait for UI bridges to respond, in milliseconds.
948# Default is 4000 (4 seconds).
949ENGINE_OPTION_UI_BRIDGES_TIMEOUT = 9
950
951# Audio buffer size.
952# Default is 512.
953ENGINE_OPTION_AUDIO_BUFFER_SIZE = 10
954
955# Audio sample rate.
956# Default is 44100.
957ENGINE_OPTION_AUDIO_SAMPLE_RATE = 11
958
959# Wherever to use 3 audio periods instead of the default 2.
960# Default is false.
961ENGINE_OPTION_AUDIO_TRIPLE_BUFFER = 12
962
963# Audio driver.
964# Default dppends on platform.
965ENGINE_OPTION_AUDIO_DRIVER = 13
966
967# Audio device (within a driver).
968# Default unset.
969ENGINE_OPTION_AUDIO_DEVICE = 14
970
971# Wherever to enable OSC support in the engine.
972ENGINE_OPTION_OSC_ENABLED = 15
973
974# The network TCP port to use for OSC.
975# A value of 0 means use a random port.
976# A value of < 0 means to not enable the TCP port for OSC.
977# @note Valid ports begin at 1024 and end at 32767 (inclusive)
978ENGINE_OPTION_OSC_PORT_TCP = 16
979
980# The network UDP port to use for OSC.
981# A value of 0 means use a random port.
982# A value of < 0 means to not enable the UDP port for OSC.
983# @note Disabling this option prevents DSSI UIs from working!
984# @note Valid ports begin at 1024 and end at 32767 (inclusive)
985ENGINE_OPTION_OSC_PORT_UDP = 17
986
987# Set path used for a specific file type.
988# Uses value as the file format, valueStr as actual path.
989ENGINE_OPTION_FILE_PATH = 18
990
991# Set path used for a specific plugin type.
992# Uses value as the plugin format, valueStr as actual path.
993# @see PluginType
994ENGINE_OPTION_PLUGIN_PATH = 19
995
996# Set path to the binary files.
997# Default unset.
998# @note Must be set for plugin and UI bridges to work
999ENGINE_OPTION_PATH_BINARIES = 20
1000
1001# Set path to the resource files.
1002# Default unset.
1003# @note Must be set for some internal plugins to work
1004ENGINE_OPTION_PATH_RESOURCES = 21
1005
1006# Prevent bad plugin and UI behaviour.
1007# @note: Linux only
1008ENGINE_OPTION_PREVENT_BAD_BEHAVIOUR = 22
1009
1010# Set background color used in the frontend, so backend can do the same for plugin UIs.
1011ENGINE_OPTION_FRONTEND_BACKGROUND_COLOR = 23
1012
1013# Set foreground color used in the frontend, so backend can do the same for plugin UIs.
1014ENGINE_OPTION_FRONTEND_FOREGROUND_COLOR = 24
1015
1016# Set UI scaling used in the frontend, so backend can do the same for plugin UIs.
1017ENGINE_OPTION_FRONTEND_UI_SCALE = 25
1018
1019# Set frontend winId, used to define as parent window for plugin UIs.
1020ENGINE_OPTION_FRONTEND_WIN_ID = 26
1021
1022# Set path to wine executable.
1023ENGINE_OPTION_WINE_EXECUTABLE = 27
1024
1025# Enable automatic wineprefix detection.
1026ENGINE_OPTION_WINE_AUTO_PREFIX = 28
1027
1028# Fallback wineprefix to use if automatic detection fails or is disabled, and WINEPREFIX is not set.
1029ENGINE_OPTION_WINE_FALLBACK_PREFIX = 29
1030
1031# Enable realtime priority for Wine application and server threads.
1032ENGINE_OPTION_WINE_RT_PRIO_ENABLED = 30
1033
1034# Base realtime priority for Wine threads.
1035ENGINE_OPTION_WINE_BASE_RT_PRIO = 31
1036
1037# Wine server realtime priority.
1038ENGINE_OPTION_WINE_SERVER_RT_PRIO = 32
1039
1040# Capture console output into debug callbacks
1041ENGINE_OPTION_DEBUG_CONSOLE_OUTPUT = 33
1042
1043# A prefix to give to all plugin clients created by Carla.
1044# Mostly useful for JACK multi-client mode.
1045# @note MUST include at least one "." (dot).
1046ENGINE_OPTION_CLIENT_NAME_PREFIX = 34
1047
1048# Treat loaded plugins as standalone (that is, there is no host UI to manage them)
1049ENGINE_OPTION_PLUGINS_ARE_STANDALONE = 35
1050
1051# ---------------------------------------------------------------------------------------------------------------------
1052# Engine Process Mode
1053# Engine process mode.
1054# @see ENGINE_OPTION_PROCESS_MODE
1055
1056# Single client mode.
1057# Inputs and outputs are added dynamically as needed by plugins.
1058ENGINE_PROCESS_MODE_SINGLE_CLIENT = 0
1059
1060# Multiple client mode.
1061# It has 1 master client + 1 client per plugin.
1062ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS = 1
1063
1064# Single client, 'rack' mode.
1065# Processes plugins in order of Id, with forced stereo always on.
1066ENGINE_PROCESS_MODE_CONTINUOUS_RACK = 2
1067
1068# Single client, 'patchbay' mode.
1069ENGINE_PROCESS_MODE_PATCHBAY = 3
1070
1071# Special mode, used in plugin-bridges only.
1072ENGINE_PROCESS_MODE_BRIDGE = 4
1073
1074# ---------------------------------------------------------------------------------------------------------------------
1075# Engine Transport Mode
1076# Engine transport mode.
1077# @see ENGINE_OPTION_TRANSPORT_MODE
1078
1079# No transport.
1080ENGINE_TRANSPORT_MODE_DISABLED = 0
1081
1082# Internal transport mode.
1083ENGINE_TRANSPORT_MODE_INTERNAL = 1
1084
1085# Transport from JACK.
1086# Only available if driver name is "JACK".
1087ENGINE_TRANSPORT_MODE_JACK = 2
1088
1089# Transport from host, used when Carla is a plugin.
1090ENGINE_TRANSPORT_MODE_PLUGIN = 3
1091
1092# Special mode, used in plugin-bridges only.
1093ENGINE_TRANSPORT_MODE_BRIDGE = 4
1094
1095# ---------------------------------------------------------------------------------------------------------------------
1096# File Callback Opcode
1097# File callback opcodes.
1098# Front-ends must always block-wait for user input.
1099# @see FileCallbackFunc and carla_set_file_callback()
1100
1101# Debug.
1102# This opcode is undefined and used only for testing purposes.
1103FILE_CALLBACK_DEBUG = 0
1104
1105# Open file or folder.
1106FILE_CALLBACK_OPEN = 1
1107
1108# Save file or folder.
1109FILE_CALLBACK_SAVE = 2
1110
1111# ---------------------------------------------------------------------------------------------------------------------
1112# Patchbay Icon
1113# The icon of a patchbay client/group.
1114
1115# Generic application icon.
1116# Used for all non-plugin clients that don't have a specific icon.
1117PATCHBAY_ICON_APPLICATION = 0
1118
1119# Plugin icon.
1120# Used for all plugin clients that don't have a specific icon.
1121PATCHBAY_ICON_PLUGIN = 1
1122
1123# Hardware icon.
1124# Used for hardware (audio or MIDI) clients.
1125PATCHBAY_ICON_HARDWARE = 2
1126
1127# Carla icon.
1128# Used for the main app.
1129PATCHBAY_ICON_CARLA = 3
1130
1131# DISTRHO icon.
1132# Used for DISTRHO based plugins.
1133PATCHBAY_ICON_DISTRHO = 4
1134
1135# File icon.
1136# Used for file type plugins (like SF2 and SFZ).
1137PATCHBAY_ICON_FILE = 5
1138
1139# ---------------------------------------------------------------------------------------------------------------------
1140# Carla Backend API (C stuff)
1141
1142# Engine callback function.
1143# Front-ends must never block indefinitely during a callback.
1144# @see EngineCallbackOpcode and carla_set_engine_callback()
1145EngineCallbackFunc = CFUNCTYPE(None, c_void_p, c_enum, c_uint, c_int, c_int, c_int, c_float, c_char_p)
1146
1147# File callback function.
1148# @see FileCallbackOpcode
1149FileCallbackFunc = CFUNCTYPE(c_char_p, c_void_p, c_enum, c_bool, c_char_p, c_char_p)
1150
1151# Parameter data.
1152class ParameterData(Structure):
1153    _fields_ = [
1154        # This parameter type.
1155        ("type", c_enum),
1156
1157        # This parameter hints.
1158        # @see ParameterHints
1159        ("hints", c_uint),
1160
1161        # Index as seen by Carla.
1162        ("index", c_int32),
1163
1164        # Real index as seen by plugins.
1165        ("rindex", c_int32),
1166
1167        # Currently mapped MIDI channel.
1168        # Counts from 0 to 15.
1169        ("midiChannel", c_uint8),
1170
1171        # Currently mapped index.
1172        # @see SpecialMappedControlIndex
1173        ("mappedControlIndex", c_int16),
1174
1175        # Minimum value that this parameter maps to.
1176        ("mappedMinimum", c_float),
1177
1178        # Maximum value that this parameter maps to.
1179        ("mappedMaximum", c_float),
1180
1181        # Flags related to the current mapping of this parameter.
1182        # @see MappedParameterFlags
1183        ("mappedFlags", c_uint)
1184    ]
1185
1186# Parameter ranges.
1187class ParameterRanges(Structure):
1188    _fields_ = [
1189        # Default value.
1190        ("def", c_float),
1191
1192        # Minimum value.
1193        ("min", c_float),
1194
1195        # Maximum value.
1196        ("max", c_float),
1197
1198        # Regular, single step value.
1199        ("step", c_float),
1200
1201        # Small step value.
1202        ("stepSmall", c_float),
1203
1204        # Large step value.
1205        ("stepLarge", c_float)
1206    ]
1207
1208# MIDI Program data.
1209class MidiProgramData(Structure):
1210    _fields_ = [
1211        # MIDI bank.
1212        ("bank", c_uint32),
1213
1214        # MIDI program.
1215        ("program", c_uint32),
1216
1217        # MIDI program name.
1218        ("name", c_char_p)
1219    ]
1220
1221# Custom data, used for saving key:value 'dictionaries'.
1222class CustomData(Structure):
1223    _fields_ = [
1224        # Value type, in URI form.
1225        # @see CustomDataTypes
1226        ("type", c_char_p),
1227
1228        # Key.
1229        # @see CustomDataKeys
1230        ("key", c_char_p),
1231
1232        # Value.
1233        ("value", c_char_p)
1234    ]
1235
1236# Engine driver device information.
1237class EngineDriverDeviceInfo(Structure):
1238    _fields_ = [
1239        # This driver device hints.
1240        # @see EngineDriverHints
1241        ("hints", c_uint),
1242
1243        # Available buffer sizes.
1244        # Terminated with 0.
1245        ("bufferSizes", POINTER(c_uint32)),
1246
1247        # Available sample rates.
1248        # Terminated with 0.0.
1249        ("sampleRates", POINTER(c_double))
1250    ]
1251
1252# ---------------------------------------------------------------------------------------------------------------------
1253# Carla Backend API (Python compatible stuff)
1254
1255# @see ParameterData
1256PyParameterData = {
1257    'type': PARAMETER_UNKNOWN,
1258    'hints': 0x0,
1259    'index': PARAMETER_NULL,
1260    'rindex': -1,
1261    'midiChannel': 0,
1262    'mappedControlIndex': CONTROL_INDEX_NONE,
1263    'mappedMinimum': 0.0,
1264    'mappedMaximum': 0.0,
1265    'mappedFlags': 0x0,
1266}
1267
1268# @see ParameterRanges
1269PyParameterRanges = {
1270    'def': 0.0,
1271    'min': 0.0,
1272    'max': 1.0,
1273    'step': 0.01,
1274    'stepSmall': 0.0001,
1275    'stepLarge': 0.1
1276}
1277
1278# @see MidiProgramData
1279PyMidiProgramData = {
1280    'bank': 0,
1281    'program': 0,
1282    'name': None
1283}
1284
1285# @see CustomData
1286PyCustomData = {
1287    'type': None,
1288    'key': None,
1289    'value': None
1290}
1291
1292# @see EngineDriverDeviceInfo
1293PyEngineDriverDeviceInfo = {
1294    'hints': 0x0,
1295    'bufferSizes': [],
1296    'sampleRates': []
1297}
1298
1299# ---------------------------------------------------------------------------------------------------------------------
1300# Carla Host API (C stuff)
1301
1302# Information about a loaded plugin.
1303# @see carla_get_plugin_info()
1304class CarlaPluginInfo(Structure):
1305    _fields_ = [
1306        # Plugin type.
1307        ("type", c_enum),
1308
1309        # Plugin category.
1310        ("category", c_enum),
1311
1312        # Plugin hints.
1313        # @see PluginHints
1314        ("hints", c_uint),
1315
1316        # Plugin options available for the user to change.
1317        # @see PluginOptions
1318        ("optionsAvailable", c_uint),
1319
1320        # Plugin options currently enabled.
1321        # Some options are enabled but not available, which means they will always be on.
1322        # @see PluginOptions
1323        ("optionsEnabled", c_uint),
1324
1325        # Plugin filename.
1326        # This can be the plugin binary or resource file.
1327        ("filename", c_char_p),
1328
1329        # Plugin name.
1330        # This name is unique within a Carla instance.
1331        # @see carla_get_real_plugin_name()
1332        ("name", c_char_p),
1333
1334        # Plugin label or URI.
1335        ("label", c_char_p),
1336
1337        # Plugin author/maker.
1338        ("maker", c_char_p),
1339
1340        # Plugin copyright/license.
1341        ("copyright", c_char_p),
1342
1343        # Icon name for this plugin, in lowercase.
1344        # Default is "plugin".
1345        ("iconName", c_char_p),
1346
1347        # Plugin unique Id.
1348        # This Id is dependent on the plugin type and may sometimes be 0.
1349        ("uniqueId", c_int64)
1350    ]
1351
1352# Port count information, used for Audio and MIDI ports and parameters.
1353# @see carla_get_audio_port_count_info()
1354# @see carla_get_midi_port_count_info()
1355# @see carla_get_parameter_count_info()
1356class CarlaPortCountInfo(Structure):
1357    _fields_ = [
1358        # Number of inputs.
1359        ("ins", c_uint32),
1360
1361        # Number of outputs.
1362        ("outs", c_uint32)
1363    ]
1364
1365# Parameter information.
1366# @see carla_get_parameter_info()
1367class CarlaParameterInfo(Structure):
1368    _fields_ = [
1369        # Parameter name.
1370        ("name", c_char_p),
1371
1372        # Parameter symbol.
1373        ("symbol", c_char_p),
1374
1375        # Parameter unit.
1376        ("unit", c_char_p),
1377
1378        # Parameter comment / documentation.
1379        ("comment", c_char_p),
1380
1381        # Parameter group name.
1382        ("groupName", c_char_p),
1383
1384        # Number of scale points.
1385        # @see CarlaScalePointInfo
1386        ("scalePointCount", c_uint32)
1387    ]
1388
1389# Parameter scale point information.
1390# @see carla_get_parameter_scalepoint_info()
1391class CarlaScalePointInfo(Structure):
1392    _fields_ = [
1393        # Scale point value.
1394        ("value", c_float),
1395
1396        # Scale point label.
1397        ("label", c_char_p)
1398    ]
1399
1400# Transport information.
1401# @see carla_get_transport_info()
1402class CarlaTransportInfo(Structure):
1403    _fields_ = [
1404        # Wherever transport is playing.
1405        ("playing", c_bool),
1406
1407        # Current transport frame.
1408        ("frame", c_uint64),
1409
1410        # Bar
1411        ("bar", c_int32),
1412
1413        # Beat
1414        ("beat", c_int32),
1415
1416        # Tick
1417        ("tick", c_int32),
1418
1419        # Beats per minute.
1420        ("bpm", c_double)
1421    ]
1422
1423# Runtime engine information.
1424class CarlaRuntimeEngineInfo(Structure):
1425    _fields_ = [
1426        # DSP load.
1427        ("load", c_float),
1428
1429        # Number of xruns.
1430        ("xruns", c_uint32)
1431    ]
1432
1433# Runtime engine driver device information.
1434class CarlaRuntimeEngineDriverDeviceInfo(Structure):
1435    _fields_ = [
1436        # Name of the driver device.
1437        ("name", c_char_p),
1438
1439        # This driver device hints.
1440        # @see EngineDriverHints
1441        ("hints", c_uint),
1442
1443        # Current buffer size.
1444        ("bufferSize", c_uint32),
1445
1446        # Available buffer sizes.
1447        # Terminated with 0.
1448        ("bufferSizes", POINTER(c_uint32)),
1449
1450        # Current sample rate.
1451        ("sampleRate", c_double),
1452
1453        # Available sample rates.
1454        # Terminated with 0.0.
1455        ("sampleRates", POINTER(c_double))
1456    ]
1457
1458# Image data for LV2 inline display API.
1459# raw image pixmap format is ARGB32,
1460class CarlaInlineDisplayImageSurface(Structure):
1461    _fields_ = [
1462        ("data", POINTER(c_ubyte)),
1463        ("width", c_int),
1464        ("height", c_int),
1465        ("stride", c_int)
1466    ]
1467
1468# ---------------------------------------------------------------------------------------------------------------------
1469# Carla Host API (Python compatible stuff)
1470
1471# @see CarlaPluginInfo
1472PyCarlaPluginInfo = {
1473    'type': PLUGIN_NONE,
1474    'category': PLUGIN_CATEGORY_NONE,
1475    'hints': 0x0,
1476    'optionsAvailable': 0x0,
1477    'optionsEnabled': 0x0,
1478    'filename': "",
1479    'name':  "",
1480    'label': "",
1481    'maker': "",
1482    'copyright': "",
1483    'iconName': "",
1484    'uniqueId': 0
1485}
1486
1487# @see CarlaPortCountInfo
1488PyCarlaPortCountInfo = {
1489    'ins': 0,
1490    'outs': 0
1491}
1492
1493# @see CarlaParameterInfo
1494PyCarlaParameterInfo = {
1495    'name': "",
1496    'symbol': "",
1497    'unit': "",
1498    'comment': "",
1499    'groupName': "",
1500    'scalePointCount': 0,
1501}
1502
1503# @see CarlaScalePointInfo
1504PyCarlaScalePointInfo = {
1505    'value': 0.0,
1506    'label': ""
1507}
1508
1509# @see CarlaTransportInfo
1510PyCarlaTransportInfo = {
1511    'playing': False,
1512    'frame': 0,
1513    'bar': 0,
1514    'beat': 0,
1515    'tick': 0,
1516    'bpm': 0.0
1517}
1518
1519# @see CarlaRuntimeEngineInfo
1520PyCarlaRuntimeEngineInfo = {
1521    'load': 0.0,
1522    'xruns': 0
1523}
1524
1525# @see CarlaRuntimeEngineDriverDeviceInfo
1526PyCarlaRuntimeEngineDriverDeviceInfo = {
1527    'name': "",
1528    'hints': 0x0,
1529    'bufferSize': 0,
1530    'bufferSizes': [],
1531    'sampleRate': 0.0,
1532    'sampleRates': []
1533}
1534
1535# ---------------------------------------------------------------------------------------------------------------------
1536# Set BINARY_NATIVE
1537
1538if WINDOWS:
1539    BINARY_NATIVE = BINARY_WIN64 if kIs64bit else BINARY_WIN32
1540else:
1541    BINARY_NATIVE = BINARY_POSIX64 if kIs64bit else BINARY_POSIX32
1542
1543# ---------------------------------------------------------------------------------------------------------------------
1544# Carla Host object (Meta)
1545
1546class CarlaHostMeta():
1547    def __init__(self):
1548        # info about this host object
1549        self.isControl = False
1550        self.isPlugin  = False
1551        self.isRemote  = False
1552        self.nsmOK     = False
1553
1554        # settings
1555        self.processMode       = ENGINE_PROCESS_MODE_PATCHBAY
1556        self.transportMode     = ENGINE_TRANSPORT_MODE_INTERNAL
1557        self.transportExtra    = ""
1558        self.nextProcessMode   = self.processMode
1559        self.processModeForced = False
1560        self.audioDriverForced = None
1561
1562        # settings
1563        self.experimental        = False
1564        self.exportLV2           = False
1565        self.forceStereo         = False
1566        self.manageUIs           = False
1567        self.maxParameters       = 0
1568        self.resetXruns          = False
1569        self.preferPluginBridges = False
1570        self.preferUIBridges     = False
1571        self.preventBadBehaviour = False
1572        self.showLogs            = False
1573        self.showPluginBridges   = False
1574        self.showWineBridges     = False
1575        self.uiBridgesTimeout    = 0
1576        self.uisAlwaysOnTop      = False
1577
1578        # settings
1579        self.pathBinaries  = ""
1580        self.pathResources = ""
1581
1582    # Get how many engine drivers are available.
1583    @abstractmethod
1584    def get_engine_driver_count(self):
1585        raise NotImplementedError
1586
1587    # Get an engine driver name.
1588    # @param index Driver index
1589    @abstractmethod
1590    def get_engine_driver_name(self, index):
1591        raise NotImplementedError
1592
1593    # Get the device names of an engine driver.
1594    # @param index Driver index
1595    @abstractmethod
1596    def get_engine_driver_device_names(self, index):
1597        raise NotImplementedError
1598
1599    # Get information about a device driver.
1600    # @param index Driver index
1601    # @param name  Device name
1602    @abstractmethod
1603    def get_engine_driver_device_info(self, index, name):
1604        raise NotImplementedError
1605
1606    # Show a device custom control panel.
1607    # @see ENGINE_DRIVER_DEVICE_HAS_CONTROL_PANEL
1608    # @param index Driver index
1609    # @param name  Device name
1610    @abstractmethod
1611    def show_engine_driver_device_control_panel(self, index, name):
1612        raise NotImplementedError
1613
1614    # Initialize the engine.
1615    # Make sure to call carla_engine_idle() at regular intervals afterwards.
1616    # @param driverName Driver to use
1617    # @param clientName Engine master client name
1618    @abstractmethod
1619    def engine_init(self, driverName, clientName):
1620        raise NotImplementedError
1621
1622    # Close the engine.
1623    # This function always closes the engine even if it returns false.
1624    # In other words, even when something goes wrong when closing the engine it still be closed nonetheless.
1625    @abstractmethod
1626    def engine_close(self):
1627        raise NotImplementedError
1628
1629    # Idle the engine.
1630    # Do not call this if the engine is not running.
1631    @abstractmethod
1632    def engine_idle(self):
1633        raise NotImplementedError
1634
1635    # Check if the engine is running.
1636    @abstractmethod
1637    def is_engine_running(self):
1638        raise NotImplementedError
1639
1640    # Get information about the currently running engine.
1641    @abstractmethod
1642    def get_runtime_engine_info(self):
1643        raise NotImplementedError
1644
1645    # Get information about the currently running engine driver device.
1646    @abstractmethod
1647    def get_runtime_engine_driver_device_info(self):
1648        raise NotImplementedError
1649
1650    # Dynamically change buffer size and/or sample rate while engine is running.
1651    # @see ENGINE_DRIVER_DEVICE_VARIABLE_BUFFER_SIZE
1652    # @see ENGINE_DRIVER_DEVICE_VARIABLE_SAMPLE_RATE
1653    def set_engine_buffer_size_and_sample_rate(self, bufferSize, sampleRate):
1654        raise NotImplementedError
1655
1656    # Show the custom control panel for the current engine device.
1657    # @see ENGINE_DRIVER_DEVICE_HAS_CONTROL_PANEL
1658    def show_engine_device_control_panel(self):
1659        raise NotImplementedError
1660
1661    # Clear the xrun count on the engine, so that the next time carla_get_runtime_engine_info() is called, it returns 0.
1662    @abstractmethod
1663    def clear_engine_xruns(self):
1664        raise NotImplementedError
1665
1666    # Tell the engine to stop the current cancelable action.
1667    # @see ENGINE_CALLBACK_CANCELABLE_ACTION
1668    @abstractmethod
1669    def cancel_engine_action(self):
1670        raise NotImplementedError
1671
1672    # Tell the engine it's about to close.
1673    # This is used to prevent the engine thread(s) from reactivating.
1674    @abstractmethod
1675    def set_engine_about_to_close(self):
1676        raise NotImplementedError
1677
1678    # Set the engine callback function.
1679    # @param func Callback function
1680    @abstractmethod
1681    def set_engine_callback(self, func):
1682        raise NotImplementedError
1683
1684    # Set an engine option.
1685    # @param option   Option
1686    # @param value    Value as number
1687    # @param valueStr Value as string
1688    @abstractmethod
1689    def set_engine_option(self, option, value, valueStr):
1690        raise NotImplementedError
1691
1692    # Set the file callback function.
1693    # @param func Callback function
1694    # @param ptr  Callback pointer
1695    @abstractmethod
1696    def set_file_callback(self, func):
1697        raise NotImplementedError
1698
1699    # Load a file of any type.
1700    # This will try to load a generic file as a plugin,
1701    # either by direct handling (SF2 and SFZ) or by using an internal plugin (like Audio and MIDI).
1702    # @see carla_get_supported_file_extensions()
1703    @abstractmethod
1704    def load_file(self, filename):
1705        raise NotImplementedError
1706
1707    # Load a Carla project file.
1708    # @note Currently loaded plugins are not removed; call carla_remove_all_plugins() first if needed.
1709    @abstractmethod
1710    def load_project(self, filename):
1711        raise NotImplementedError
1712
1713    # Save current project to a file.
1714    @abstractmethod
1715    def save_project(self, filename):
1716        raise NotImplementedError
1717
1718    # Clear the currently set project filename.
1719    @abstractmethod
1720    def clear_project_filename(self):
1721        raise NotImplementedError
1722
1723    # Connect two patchbay ports.
1724    # @param groupIdA Output group
1725    # @param portIdA  Output port
1726    # @param groupIdB Input group
1727    # @param portIdB  Input port
1728    # @see ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED
1729    @abstractmethod
1730    def patchbay_connect(self, external, groupIdA, portIdA, groupIdB, portIdB):
1731        raise NotImplementedError
1732
1733    # Disconnect two patchbay ports.
1734    # @param connectionId Connection Id
1735    # @see ENGINE_CALLBACK_PATCHBAY_CONNECTION_REMOVED
1736    @abstractmethod
1737    def patchbay_disconnect(self, external, connectionId):
1738        raise NotImplementedError
1739
1740    # Set the position of a group.
1741    # This is purely cached and saved in the project file, Carla backend does nothing with the value.
1742    # When loading a project, callbacks are used to inform of the previously saved positions.
1743    # @see ENGINE_CALLBACK_PATCHBAY_CLIENT_POSITION_CHANGED
1744    @abstractmethod
1745    def patchbay_set_group_pos(self, external, groupId, x1, y1, x2, y2):
1746        raise NotImplementedError
1747
1748    # Force the engine to resend all patchbay clients, ports and connections again.
1749    # @param external Wherever to show external/hardware ports instead of internal ones.
1750    #                 Only valid in patchbay engine mode, other modes will ignore this.
1751    @abstractmethod
1752    def patchbay_refresh(self, external):
1753        raise NotImplementedError
1754
1755    # Start playback of the engine transport.
1756    @abstractmethod
1757    def transport_play(self):
1758        raise NotImplementedError
1759
1760    # Pause the engine transport.
1761    @abstractmethod
1762    def transport_pause(self):
1763        raise NotImplementedError
1764
1765    # Pause the engine transport.
1766    @abstractmethod
1767    def transport_bpm(self, bpm):
1768        raise NotImplementedError
1769
1770    # Relocate the engine transport to a specific frame.
1771    @abstractmethod
1772    def transport_relocate(self, frame):
1773        raise NotImplementedError
1774
1775    # Get the current transport frame.
1776    @abstractmethod
1777    def get_current_transport_frame(self):
1778        raise NotImplementedError
1779
1780    # Get the engine transport information.
1781    @abstractmethod
1782    def get_transport_info(self):
1783        raise NotImplementedError
1784
1785    # Current number of plugins loaded.
1786    @abstractmethod
1787    def get_current_plugin_count(self):
1788        raise NotImplementedError
1789
1790    # Maximum number of loadable plugins allowed.
1791    # Returns 0 if engine is not started.
1792    @abstractmethod
1793    def get_max_plugin_number(self):
1794        raise NotImplementedError
1795
1796    # Add a new plugin.
1797    # If you don't know the binary type use the BINARY_NATIVE macro.
1798    # @param btype    Binary type
1799    # @param ptype    Plugin type
1800    # @param filename Filename, if applicable
1801    # @param name     Name of the plugin, can be NULL
1802    # @param label    Plugin label, if applicable
1803    # @param uniqueId Plugin unique Id, if applicable
1804    # @param extraPtr Extra pointer, defined per plugin type
1805    # @param options  Initial plugin options
1806    @abstractmethod
1807    def add_plugin(self, btype, ptype, filename, name, label, uniqueId, extraPtr, options):
1808        raise NotImplementedError
1809
1810    # Remove a plugin.
1811    # @param pluginId Plugin to remove.
1812    @abstractmethod
1813    def remove_plugin(self, pluginId):
1814        raise NotImplementedError
1815
1816    # Remove all plugins.
1817    @abstractmethod
1818    def remove_all_plugins(self):
1819        raise NotImplementedError
1820
1821    # Rename a plugin.
1822    # Returns the new name, or NULL if the operation failed.
1823    # @param pluginId Plugin to rename
1824    # @param newName  New plugin name
1825    @abstractmethod
1826    def rename_plugin(self, pluginId, newName):
1827        raise NotImplementedError
1828
1829    # Clone a plugin.
1830    # @param pluginId Plugin to clone
1831    @abstractmethod
1832    def clone_plugin(self, pluginId):
1833        raise NotImplementedError
1834
1835    # Prepare replace of a plugin.
1836    # The next call to carla_add_plugin() will use this id, replacing the current plugin.
1837    # @param pluginId Plugin to replace
1838    # @note This function requires carla_add_plugin() to be called afterwards *as soon as possible*.
1839    @abstractmethod
1840    def replace_plugin(self, pluginId):
1841        raise NotImplementedError
1842
1843    # Switch two plugins positions.
1844    # @param pluginIdA Plugin A
1845    # @param pluginIdB Plugin B
1846    @abstractmethod
1847    def switch_plugins(self, pluginIdA, pluginIdB):
1848        raise NotImplementedError
1849
1850    # Load a plugin state.
1851    # @param pluginId Plugin
1852    # @param filename Path to plugin state
1853    # @see carla_save_plugin_state()
1854    @abstractmethod
1855    def load_plugin_state(self, pluginId, filename):
1856        raise NotImplementedError
1857
1858    # Save a plugin state.
1859    # @param pluginId Plugin
1860    # @param filename Path to plugin state
1861    # @see carla_load_plugin_state()
1862    @abstractmethod
1863    def save_plugin_state(self, pluginId, filename):
1864        raise NotImplementedError
1865
1866    # Export plugin as LV2.
1867    # @param pluginId Plugin
1868    # @param lv2path Path to lv2 plugin folder
1869    def export_plugin_lv2(self, pluginId, lv2path):
1870        raise NotImplementedError
1871
1872    # Get information from a plugin.
1873    # @param pluginId Plugin
1874    @abstractmethod
1875    def get_plugin_info(self, pluginId):
1876        raise NotImplementedError
1877
1878    # Get audio port count information from a plugin.
1879    # @param pluginId Plugin
1880    @abstractmethod
1881    def get_audio_port_count_info(self, pluginId):
1882        raise NotImplementedError
1883
1884    # Get MIDI port count information from a plugin.
1885    # @param pluginId Plugin
1886    @abstractmethod
1887    def get_midi_port_count_info(self, pluginId):
1888        raise NotImplementedError
1889
1890    # Get parameter count information from a plugin.
1891    # @param pluginId Plugin
1892    @abstractmethod
1893    def get_parameter_count_info(self, pluginId):
1894        raise NotImplementedError
1895
1896    # Get parameter information from a plugin.
1897    # @param pluginId    Plugin
1898    # @param parameterId Parameter index
1899    # @see carla_get_parameter_count()
1900    @abstractmethod
1901    def get_parameter_info(self, pluginId, parameterId):
1902        raise NotImplementedError
1903
1904    # Get parameter scale point information from a plugin.
1905    # @param pluginId     Plugin
1906    # @param parameterId  Parameter index
1907    # @param scalePointId Parameter scale-point index
1908    # @see CarlaParameterInfo::scalePointCount
1909    @abstractmethod
1910    def get_parameter_scalepoint_info(self, pluginId, parameterId, scalePointId):
1911        raise NotImplementedError
1912
1913    # Get a plugin's parameter data.
1914    # @param pluginId    Plugin
1915    # @param parameterId Parameter index
1916    # @see carla_get_parameter_count()
1917    @abstractmethod
1918    def get_parameter_data(self, pluginId, parameterId):
1919        raise NotImplementedError
1920
1921    # Get a plugin's parameter ranges.
1922    # @param pluginId    Plugin
1923    # @param parameterId Parameter index
1924    # @see carla_get_parameter_count()
1925    @abstractmethod
1926    def get_parameter_ranges(self, pluginId, parameterId):
1927        raise NotImplementedError
1928
1929    # Get a plugin's MIDI program data.
1930    # @param pluginId      Plugin
1931    # @param midiProgramId MIDI Program index
1932    # @see carla_get_midi_program_count()
1933    @abstractmethod
1934    def get_midi_program_data(self, pluginId, midiProgramId):
1935        raise NotImplementedError
1936
1937    # Get a plugin's custom data, using index.
1938    # @param pluginId     Plugin
1939    # @param customDataId Custom data index
1940    # @see carla_get_custom_data_count()
1941    @abstractmethod
1942    def get_custom_data(self, pluginId, customDataId):
1943        raise NotImplementedError
1944
1945    # Get a plugin's custom data value, using type and key.
1946    # @param pluginId Plugin
1947    # @param type     Custom data type
1948    # @param key      Custom data key
1949    # @see carla_get_custom_data_count()
1950    @abstractmethod
1951    def get_custom_data_value(self, pluginId, type_, key):
1952        raise NotImplementedError
1953
1954    # Get a plugin's chunk data.
1955    # @param pluginId Plugin
1956    # @see PLUGIN_OPTION_USE_CHUNKS
1957    @abstractmethod
1958    def get_chunk_data(self, pluginId):
1959        raise NotImplementedError
1960
1961    # Get how many parameters a plugin has.
1962    # @param pluginId Plugin
1963    @abstractmethod
1964    def get_parameter_count(self, pluginId):
1965        raise NotImplementedError
1966
1967    # Get how many programs a plugin has.
1968    # @param pluginId Plugin
1969    # @see carla_get_program_name()
1970    @abstractmethod
1971    def get_program_count(self, pluginId):
1972        raise NotImplementedError
1973
1974    # Get how many MIDI programs a plugin has.
1975    # @param pluginId Plugin
1976    # @see carla_get_midi_program_name() and carla_get_midi_program_data()
1977    @abstractmethod
1978    def get_midi_program_count(self, pluginId):
1979        raise NotImplementedError
1980
1981    # Get how many custom data sets a plugin has.
1982    # @param pluginId Plugin
1983    # @see carla_get_custom_data()
1984    @abstractmethod
1985    def get_custom_data_count(self, pluginId):
1986        raise NotImplementedError
1987
1988    # Get a plugin's parameter text (custom display of internal values).
1989    # @param pluginId    Plugin
1990    # @param parameterId Parameter index
1991    # @see PARAMETER_USES_CUSTOM_TEXT
1992    @abstractmethod
1993    def get_parameter_text(self, pluginId, parameterId):
1994        raise NotImplementedError
1995
1996    # Get a plugin's program name.
1997    # @param pluginId  Plugin
1998    # @param programId Program index
1999    # @see carla_get_program_count()
2000    @abstractmethod
2001    def get_program_name(self, pluginId, programId):
2002        raise NotImplementedError
2003
2004    # Get a plugin's MIDI program name.
2005    # @param pluginId      Plugin
2006    # @param midiProgramId MIDI Program index
2007    # @see carla_get_midi_program_count()
2008    @abstractmethod
2009    def get_midi_program_name(self, pluginId, midiProgramId):
2010        raise NotImplementedError
2011
2012    # Get a plugin's real name.
2013    # This is the name the plugin uses to identify itself; may not be unique.
2014    # @param pluginId Plugin
2015    @abstractmethod
2016    def get_real_plugin_name(self, pluginId):
2017        raise NotImplementedError
2018
2019    # Get a plugin's program index.
2020    # @param pluginId Plugin
2021    @abstractmethod
2022    def get_current_program_index(self, pluginId):
2023        raise NotImplementedError
2024
2025    # Get a plugin's midi program index.
2026    # @param pluginId Plugin
2027    @abstractmethod
2028    def get_current_midi_program_index(self, pluginId):
2029        raise NotImplementedError
2030
2031    # Get a plugin's default parameter value.
2032    # @param pluginId    Plugin
2033    # @param parameterId Parameter index
2034    @abstractmethod
2035    def get_default_parameter_value(self, pluginId, parameterId):
2036        raise NotImplementedError
2037
2038    # Get a plugin's current parameter value.
2039    # @param pluginId    Plugin
2040    # @param parameterId Parameter index
2041    @abstractmethod
2042    def get_current_parameter_value(self, pluginId, parameterId):
2043        raise NotImplementedError
2044
2045    # Get a plugin's internal parameter value.
2046    # @param pluginId    Plugin
2047    # @param parameterId Parameter index, maybe be negative
2048    # @see InternalParameterIndex
2049    @abstractmethod
2050    def get_internal_parameter_value(self, pluginId, parameterId):
2051        raise NotImplementedError
2052
2053    # Get a plugin's input peak value.
2054    # @param pluginId Plugin
2055    # @param isLeft   Wherever to get the left/mono value, otherwise right.
2056    @abstractmethod
2057    def get_input_peak_value(self, pluginId, isLeft):
2058        raise NotImplementedError
2059
2060    # Get a plugin's output peak value.
2061    # @param pluginId Plugin
2062    # @param isLeft   Wherever to get the left/mono value, otherwise right.
2063    @abstractmethod
2064    def get_output_peak_value(self, pluginId, isLeft):
2065        raise NotImplementedError
2066
2067    # Render a plugin's inline display.
2068    # @param pluginId Plugin
2069    @abstractmethod
2070    def render_inline_display(self, pluginId, width, height):
2071        raise NotImplementedError
2072
2073    # Enable a plugin's option.
2074    # @param pluginId Plugin
2075    # @param option   An option from PluginOptions
2076    # @param yesNo    New enabled state
2077    @abstractmethod
2078    def set_option(self, pluginId, option, yesNo):
2079        raise NotImplementedError
2080
2081    # Enable or disable a plugin.
2082    # @param pluginId Plugin
2083    # @param onOff    New active state
2084    @abstractmethod
2085    def set_active(self, pluginId, onOff):
2086        raise NotImplementedError
2087
2088    # Change a plugin's internal dry/wet.
2089    # @param pluginId Plugin
2090    # @param value    New dry/wet value
2091    @abstractmethod
2092    def set_drywet(self, pluginId, value):
2093        raise NotImplementedError
2094
2095    # Change a plugin's internal volume.
2096    # @param pluginId Plugin
2097    # @param value    New volume
2098    @abstractmethod
2099    def set_volume(self, pluginId, value):
2100        raise NotImplementedError
2101
2102    # Change a plugin's internal stereo balance, left channel.
2103    # @param pluginId Plugin
2104    # @param value    New value
2105    @abstractmethod
2106    def set_balance_left(self, pluginId, value):
2107        raise NotImplementedError
2108
2109    # Change a plugin's internal stereo balance, right channel.
2110    # @param pluginId Plugin
2111    # @param value    New value
2112    @abstractmethod
2113    def set_balance_right(self, pluginId, value):
2114        raise NotImplementedError
2115
2116    # Change a plugin's internal mono panning value.
2117    # @param pluginId Plugin
2118    # @param value    New value
2119    @abstractmethod
2120    def set_panning(self, pluginId, value):
2121        raise NotImplementedError
2122
2123    # Change a plugin's internal control channel.
2124    # @param pluginId Plugin
2125    # @param channel  New channel
2126    @abstractmethod
2127    def set_ctrl_channel(self, pluginId, channel):
2128        raise NotImplementedError
2129
2130    # Change a plugin's parameter value.
2131    # @param pluginId    Plugin
2132    # @param parameterId Parameter index
2133    # @param value       New value
2134    @abstractmethod
2135    def set_parameter_value(self, pluginId, parameterId, value):
2136        raise NotImplementedError
2137
2138    # Change a plugin's parameter mapped control index.
2139    # @param pluginId    Plugin
2140    # @param parameterId Parameter index
2141    # @param cc          New MIDI cc
2142    @abstractmethod
2143    def set_parameter_midi_channel(self, pluginId, parameterId, channel):
2144        raise NotImplementedError
2145
2146    # Change a plugin's parameter MIDI channel.
2147    # @param pluginId    Plugin
2148    # @param parameterId Parameter index
2149    # @param channel     New control index
2150    @abstractmethod
2151    def set_parameter_mapped_control_index(self, pluginId, parameterId, index):
2152        raise NotImplementedError
2153
2154    # Change a plugin's parameter mapped range.
2155    # @param pluginId    Plugin
2156    # @param parameterId Parameter index
2157    # @param minimum     New mapped minimum
2158    # @param maximum     New mapped maximum
2159    @abstractmethod
2160    def set_parameter_mapped_range(self, pluginId, parameterId, minimum, maximum):
2161        raise NotImplementedError
2162
2163    # Change a plugin's parameter in drag/touch mode state.
2164    # Usually happens from a UI when the user is moving a parameter with a mouse or similar input.
2165    # @param pluginId    Plugin
2166    # @param parameterId Parameter index
2167    # @param touch       New state
2168    @abstractmethod
2169    def set_parameter_touch(self, pluginId, parameterId, touch):
2170        raise NotImplementedError
2171
2172    # Change a plugin's current program.
2173    # @param pluginId  Plugin
2174    # @param programId New program
2175    @abstractmethod
2176    def set_program(self, pluginId, programId):
2177        raise NotImplementedError
2178
2179    # Change a plugin's current MIDI program.
2180    # @param pluginId      Plugin
2181    # @param midiProgramId New value
2182    @abstractmethod
2183    def set_midi_program(self, pluginId, midiProgramId):
2184        raise NotImplementedError
2185
2186    # Set a plugin's custom data set.
2187    # @param pluginId Plugin
2188    # @param type     Type
2189    # @param key      Key
2190    # @param value    New value
2191    # @see CustomDataTypes and CustomDataKeys
2192    @abstractmethod
2193    def set_custom_data(self, pluginId, type_, key, value):
2194        raise NotImplementedError
2195
2196    # Set a plugin's chunk data.
2197    # @param pluginId  Plugin
2198    # @param chunkData New chunk data
2199    # @see PLUGIN_OPTION_USE_CHUNKS and carla_get_chunk_data()
2200    @abstractmethod
2201    def set_chunk_data(self, pluginId, chunkData):
2202        raise NotImplementedError
2203
2204    # Tell a plugin to prepare for save.
2205    # This should be called before saving custom data sets.
2206    # @param pluginId Plugin
2207    @abstractmethod
2208    def prepare_for_save(self, pluginId):
2209        raise NotImplementedError
2210
2211    # Reset all plugin's parameters.
2212    # @param pluginId Plugin
2213    @abstractmethod
2214    def reset_parameters(self, pluginId):
2215        raise NotImplementedError
2216
2217    # Randomize all plugin's parameters.
2218    # @param pluginId Plugin
2219    @abstractmethod
2220    def randomize_parameters(self, pluginId):
2221        raise NotImplementedError
2222
2223    # Send a single note of a plugin.
2224    # If velocity is 0, note-off is sent; note-on otherwise.
2225    # @param pluginId Plugin
2226    # @param channel  Note channel
2227    # @param note     Note pitch
2228    # @param velocity Note velocity
2229    @abstractmethod
2230    def send_midi_note(self, pluginId, channel, note, velocity):
2231        raise NotImplementedError
2232
2233    # Tell a plugin to show its own custom UI.
2234    # @param pluginId Plugin
2235    # @param yesNo    New UI state, visible or not
2236    # @see PLUGIN_HAS_CUSTOM_UI
2237    @abstractmethod
2238    def show_custom_ui(self, pluginId, yesNo):
2239        raise NotImplementedError
2240
2241    # Get the current engine buffer size.
2242    @abstractmethod
2243    def get_buffer_size(self):
2244        raise NotImplementedError
2245
2246    # Get the current engine sample rate.
2247    @abstractmethod
2248    def get_sample_rate(self):
2249        raise NotImplementedError
2250
2251    # Get the last error.
2252    @abstractmethod
2253    def get_last_error(self):
2254        raise NotImplementedError
2255
2256    # Get the current engine OSC URL (TCP).
2257    @abstractmethod
2258    def get_host_osc_url_tcp(self):
2259        raise NotImplementedError
2260
2261    # Get the current engine OSC URL (UDP).
2262    @abstractmethod
2263    def get_host_osc_url_udp(self):
2264        raise NotImplementedError
2265
2266    # Initialize NSM (that is, announce ourselves to it).
2267    # Must be called as early as possible in the program's lifecycle.
2268    # Returns true if NSM is available and initialized correctly.
2269    @abstractmethod
2270    def nsm_init(self, pid, executableName):
2271        raise NotImplementedError
2272
2273    # Respond to an NSM callback.
2274    @abstractmethod
2275    def nsm_ready(self, opcode):
2276        raise NotImplementedError
2277
2278# ---------------------------------------------------------------------------------------------------------------------
2279# Carla Host object (dummy/null, does nothing)
2280
2281class CarlaHostNull(CarlaHostMeta):
2282    def __init__(self):
2283        CarlaHostMeta.__init__(self)
2284
2285        self.fEngineCallback = None
2286        self.fFileCallback   = None
2287        self.fEngineRunning  = False
2288
2289    def get_engine_driver_count(self):
2290        return 0
2291
2292    def get_engine_driver_name(self, index):
2293        return ""
2294
2295    def get_engine_driver_device_names(self, index):
2296        return []
2297
2298    def get_engine_driver_device_info(self, index, name):
2299        return PyEngineDriverDeviceInfo
2300
2301    def show_engine_driver_device_control_panel(self, index, name):
2302        return False
2303
2304    def engine_init(self, driverName, clientName):
2305        self.fEngineRunning = True
2306        if self.fEngineCallback is not None:
2307            self.fEngineCallback(None,
2308                                 ENGINE_CALLBACK_ENGINE_STARTED,
2309                                 0,
2310                                 self.processMode,
2311                                 self.transportMode,
2312                                 0, 0.0,
2313                                 driverName)
2314        return True
2315
2316    def engine_close(self):
2317        self.fEngineRunning = False
2318        if self.fEngineCallback is not None:
2319            self.fEngineCallback(None, ENGINE_CALLBACK_ENGINE_STOPPED, 0, 0, 0, 0, 0.0, "")
2320        return True
2321
2322    def engine_idle(self):
2323        return
2324
2325    def is_engine_running(self):
2326        return self.fEngineRunning
2327
2328    def get_runtime_engine_info(self):
2329        return PyCarlaRuntimeEngineInfo
2330
2331    def get_runtime_engine_driver_device_info(self):
2332        return PyCarlaRuntimeEngineDriverDeviceInfo
2333
2334    def set_engine_buffer_size_and_sample_rate(self, bufferSize, sampleRate):
2335        return False
2336
2337    def show_engine_device_control_panel(self):
2338        return False
2339
2340    def clear_engine_xruns(self):
2341        return
2342
2343    def cancel_engine_action(self):
2344        return
2345
2346    def set_engine_about_to_close(self):
2347        return True
2348
2349    def set_engine_callback(self, func):
2350        self.fEngineCallback = func
2351
2352    def set_engine_option(self, option, value, valueStr):
2353        return
2354
2355    def set_file_callback(self, func):
2356        self.fFileCallback = func
2357
2358    def load_file(self, filename):
2359        return False
2360
2361    def load_project(self, filename):
2362        return False
2363
2364    def save_project(self, filename):
2365        return False
2366
2367    def clear_project_filename(self):
2368        return
2369
2370    def patchbay_connect(self, external, groupIdA, portIdA, groupIdB, portIdB):
2371        return False
2372
2373    def patchbay_disconnect(self, external, connectionId):
2374        return False
2375
2376    def patchbay_set_group_pos(self, external, groupId, x1, y1, x2, y2):
2377        return False
2378
2379    def patchbay_refresh(self, external):
2380        return False
2381
2382    def transport_play(self):
2383        return
2384
2385    def transport_pause(self):
2386        return
2387
2388    def transport_bpm(self, bpm):
2389        return
2390
2391    def transport_relocate(self, frame):
2392        return
2393
2394    def get_current_transport_frame(self):
2395        return 0
2396
2397    def get_transport_info(self):
2398        return PyCarlaTransportInfo
2399
2400    def get_current_plugin_count(self):
2401        return 0
2402
2403    def get_max_plugin_number(self):
2404        return 0
2405
2406    def add_plugin(self, btype, ptype, filename, name, label, uniqueId, extraPtr, options):
2407        return False
2408
2409    def remove_plugin(self, pluginId):
2410        return False
2411
2412    def remove_all_plugins(self):
2413        return False
2414
2415    def rename_plugin(self, pluginId, newName):
2416        return False
2417
2418    def clone_plugin(self, pluginId):
2419        return False
2420
2421    def replace_plugin(self, pluginId):
2422        return False
2423
2424    def switch_plugins(self, pluginIdA, pluginIdB):
2425        return False
2426
2427    def load_plugin_state(self, pluginId, filename):
2428        return False
2429
2430    def save_plugin_state(self, pluginId, filename):
2431        return False
2432
2433    def export_plugin_lv2(self, pluginId, lv2path):
2434        return False
2435
2436    def get_plugin_info(self, pluginId):
2437        return PyCarlaPluginInfo
2438
2439    def get_audio_port_count_info(self, pluginId):
2440        return PyCarlaPortCountInfo
2441
2442    def get_midi_port_count_info(self, pluginId):
2443        return PyCarlaPortCountInfo
2444
2445    def get_parameter_count_info(self, pluginId):
2446        return PyCarlaPortCountInfo
2447
2448    def get_parameter_info(self, pluginId, parameterId):
2449        return PyCarlaParameterInfo
2450
2451    def get_parameter_scalepoint_info(self, pluginId, parameterId, scalePointId):
2452        return PyCarlaScalePointInfo
2453
2454    def get_parameter_data(self, pluginId, parameterId):
2455        return PyParameterData
2456
2457    def get_parameter_ranges(self, pluginId, parameterId):
2458        return PyParameterRanges
2459
2460    def get_midi_program_data(self, pluginId, midiProgramId):
2461        return PyMidiProgramData
2462
2463    def get_custom_data(self, pluginId, customDataId):
2464        return PyCustomData
2465
2466    def get_custom_data_value(self, pluginId, type_, key):
2467        return ""
2468
2469    def get_chunk_data(self, pluginId):
2470        return ""
2471
2472    def get_parameter_count(self, pluginId):
2473        return 0
2474
2475    def get_program_count(self, pluginId):
2476        return 0
2477
2478    def get_midi_program_count(self, pluginId):
2479        return 0
2480
2481    def get_custom_data_count(self, pluginId):
2482        return 0
2483
2484    def get_parameter_text(self, pluginId, parameterId):
2485        return ""
2486
2487    def get_program_name(self, pluginId, programId):
2488        return ""
2489
2490    def get_midi_program_name(self, pluginId, midiProgramId):
2491        return ""
2492
2493    def get_real_plugin_name(self, pluginId):
2494        return ""
2495
2496    def get_current_program_index(self, pluginId):
2497        return 0
2498
2499    def get_current_midi_program_index(self, pluginId):
2500        return 0
2501
2502    def get_default_parameter_value(self, pluginId, parameterId):
2503        return 0.0
2504
2505    def get_current_parameter_value(self, pluginId, parameterId):
2506        return 0.0
2507
2508    def get_internal_parameter_value(self, pluginId, parameterId):
2509        return 0.0
2510
2511    def get_input_peak_value(self, pluginId, isLeft):
2512        return 0.0
2513
2514    def get_output_peak_value(self, pluginId, isLeft):
2515        return 0.0
2516
2517    def render_inline_display(self, pluginId, width, height):
2518        return None
2519
2520    def set_option(self, pluginId, option, yesNo):
2521        return
2522
2523    def set_active(self, pluginId, onOff):
2524        return
2525
2526    def set_drywet(self, pluginId, value):
2527        return
2528
2529    def set_volume(self, pluginId, value):
2530        return
2531
2532    def set_balance_left(self, pluginId, value):
2533        return
2534
2535    def set_balance_right(self, pluginId, value):
2536        return
2537
2538    def set_panning(self, pluginId, value):
2539        return
2540
2541    def set_ctrl_channel(self, pluginId, channel):
2542        return
2543
2544    def set_parameter_value(self, pluginId, parameterId, value):
2545        return
2546
2547    def set_parameter_midi_channel(self, pluginId, parameterId, channel):
2548        return
2549
2550    def set_parameter_mapped_control_index(self, pluginId, parameterId, index):
2551        return
2552
2553    def set_parameter_mapped_range(self, pluginId, parameterId, minimum, maximum):
2554        return
2555
2556    def set_parameter_touch(self, pluginId, parameterId, touch):
2557        return
2558
2559    def set_program(self, pluginId, programId):
2560        return
2561
2562    def set_midi_program(self, pluginId, midiProgramId):
2563        return
2564
2565    def set_custom_data(self, pluginId, type_, key, value):
2566        return
2567
2568    def set_chunk_data(self, pluginId, chunkData):
2569        return
2570
2571    def prepare_for_save(self, pluginId):
2572        return
2573
2574    def reset_parameters(self, pluginId):
2575        return
2576
2577    def randomize_parameters(self, pluginId):
2578        return
2579
2580    def send_midi_note(self, pluginId, channel, note, velocity):
2581        return
2582
2583    def show_custom_ui(self, pluginId, yesNo):
2584        return
2585
2586    def get_buffer_size(self):
2587        return 0
2588
2589    def get_sample_rate(self):
2590        return 0.0
2591
2592    def get_last_error(self):
2593        return ""
2594
2595    def get_host_osc_url_tcp(self):
2596        return ""
2597
2598    def get_host_osc_url_udp(self):
2599        return ""
2600
2601    def nsm_init(self, pid, executableName):
2602        return False
2603
2604    def nsm_ready(self, opcode):
2605        return
2606
2607# ---------------------------------------------------------------------------------------------------------------------
2608# Carla Host object using a DLL
2609
2610class CarlaHostDLL(CarlaHostMeta):
2611    def __init__(self, libName, loadGlobal):
2612        CarlaHostMeta.__init__(self)
2613
2614        # info about this host object
2615        self.isPlugin = False
2616
2617        self.lib = CDLL(libName, RTLD_GLOBAL if loadGlobal else RTLD_LOCAL)
2618
2619        self.lib.carla_get_engine_driver_count.argtypes = None
2620        self.lib.carla_get_engine_driver_count.restype = c_uint
2621
2622        self.lib.carla_get_engine_driver_name.argtypes = (c_uint,)
2623        self.lib.carla_get_engine_driver_name.restype = c_char_p
2624
2625        self.lib.carla_get_engine_driver_device_names.argtypes = (c_uint,)
2626        self.lib.carla_get_engine_driver_device_names.restype = POINTER(c_char_p)
2627
2628        self.lib.carla_get_engine_driver_device_info.argtypes = (c_uint, c_char_p)
2629        self.lib.carla_get_engine_driver_device_info.restype = POINTER(EngineDriverDeviceInfo)
2630
2631        self.lib.carla_show_engine_driver_device_control_panel.argtypes = (c_uint, c_char_p)
2632        self.lib.carla_show_engine_driver_device_control_panel.restype = c_bool
2633
2634        self.lib.carla_standalone_host_init.argtypes = None
2635        self.lib.carla_standalone_host_init.restype = c_void_p
2636
2637        self.lib.carla_engine_init.argtypes = (c_void_p, c_char_p, c_char_p)
2638        self.lib.carla_engine_init.restype = c_bool
2639
2640        self.lib.carla_engine_close.argtypes = (c_void_p,)
2641        self.lib.carla_engine_close.restype = c_bool
2642
2643        self.lib.carla_engine_idle.argtypes = (c_void_p,)
2644        self.lib.carla_engine_idle.restype = None
2645
2646        self.lib.carla_is_engine_running.argtypes = (c_void_p,)
2647        self.lib.carla_is_engine_running.restype = c_bool
2648
2649        self.lib.carla_get_runtime_engine_info.argtypes = (c_void_p,)
2650        self.lib.carla_get_runtime_engine_info.restype = POINTER(CarlaRuntimeEngineInfo)
2651
2652        self.lib.carla_get_runtime_engine_driver_device_info.argtypes = (c_void_p,)
2653        self.lib.carla_get_runtime_engine_driver_device_info.restype = POINTER(CarlaRuntimeEngineDriverDeviceInfo)
2654
2655        self.lib.carla_set_engine_buffer_size_and_sample_rate.argtypes = (c_void_p, c_uint, c_double)
2656        self.lib.carla_set_engine_buffer_size_and_sample_rate.restype = c_bool
2657
2658        self.lib.carla_show_engine_device_control_panel.argtypes = (c_void_p,)
2659        self.lib.carla_show_engine_device_control_panel.restype = c_bool
2660
2661        self.lib.carla_clear_engine_xruns.argtypes = (c_void_p,)
2662        self.lib.carla_clear_engine_xruns.restype = None
2663
2664        self.lib.carla_cancel_engine_action.argtypes = (c_void_p,)
2665        self.lib.carla_cancel_engine_action.restype = None
2666
2667        self.lib.carla_set_engine_about_to_close.argtypes = (c_void_p,)
2668        self.lib.carla_set_engine_about_to_close.restype = c_bool
2669
2670        self.lib.carla_set_engine_callback.argtypes = (c_void_p, EngineCallbackFunc, c_void_p)
2671        self.lib.carla_set_engine_callback.restype = None
2672
2673        self.lib.carla_set_engine_option.argtypes = (c_void_p, c_enum, c_int, c_char_p)
2674        self.lib.carla_set_engine_option.restype = None
2675
2676        self.lib.carla_set_file_callback.argtypes = (c_void_p, FileCallbackFunc, c_void_p)
2677        self.lib.carla_set_file_callback.restype = None
2678
2679        self.lib.carla_load_file.argtypes = (c_void_p, c_char_p)
2680        self.lib.carla_load_file.restype = c_bool
2681
2682        self.lib.carla_load_project.argtypes = (c_void_p, c_char_p)
2683        self.lib.carla_load_project.restype = c_bool
2684
2685        self.lib.carla_save_project.argtypes = (c_void_p, c_char_p)
2686        self.lib.carla_save_project.restype = c_bool
2687
2688        self.lib.carla_clear_project_filename.argtypes = (c_void_p,)
2689        self.lib.carla_clear_project_filename.restype = None
2690
2691        self.lib.carla_patchbay_connect.argtypes = (c_void_p, c_bool, c_uint, c_uint, c_uint, c_uint)
2692        self.lib.carla_patchbay_connect.restype = c_bool
2693
2694        self.lib.carla_patchbay_disconnect.argtypes = (c_void_p, c_bool, c_uint)
2695        self.lib.carla_patchbay_disconnect.restype = c_bool
2696
2697        self.lib.carla_patchbay_set_group_pos.argtypes = (c_void_p, c_bool, c_uint, c_int, c_int, c_int, c_int)
2698        self.lib.carla_patchbay_set_group_pos.restype = c_bool
2699
2700        self.lib.carla_patchbay_refresh.argtypes = (c_void_p, c_bool)
2701        self.lib.carla_patchbay_refresh.restype = c_bool
2702
2703        self.lib.carla_transport_play.argtypes = (c_void_p,)
2704        self.lib.carla_transport_play.restype = None
2705
2706        self.lib.carla_transport_pause.argtypes = (c_void_p,)
2707        self.lib.carla_transport_pause.restype = None
2708
2709        self.lib.carla_transport_bpm.argtypes = (c_void_p, c_double)
2710        self.lib.carla_transport_bpm.restype = None
2711
2712        self.lib.carla_transport_relocate.argtypes = (c_void_p, c_uint64)
2713        self.lib.carla_transport_relocate.restype = None
2714
2715        self.lib.carla_get_current_transport_frame.argtypes = (c_void_p,)
2716        self.lib.carla_get_current_transport_frame.restype = c_uint64
2717
2718        self.lib.carla_get_transport_info.argtypes = (c_void_p,)
2719        self.lib.carla_get_transport_info.restype = POINTER(CarlaTransportInfo)
2720
2721        self.lib.carla_get_current_plugin_count.argtypes = (c_void_p,)
2722        self.lib.carla_get_current_plugin_count.restype = c_uint32
2723
2724        self.lib.carla_get_max_plugin_number.argtypes = (c_void_p,)
2725        self.lib.carla_get_max_plugin_number.restype = c_uint32
2726
2727        self.lib.carla_add_plugin.argtypes = (c_void_p, c_enum, c_enum, c_char_p, c_char_p, c_char_p, c_int64,
2728                                              c_void_p, c_uint)
2729        self.lib.carla_add_plugin.restype = c_bool
2730
2731        self.lib.carla_remove_plugin.argtypes = (c_void_p, c_uint)
2732        self.lib.carla_remove_plugin.restype = c_bool
2733
2734        self.lib.carla_remove_all_plugins.argtypes = (c_void_p,)
2735        self.lib.carla_remove_all_plugins.restype = c_bool
2736
2737        self.lib.carla_rename_plugin.argtypes = (c_void_p, c_uint, c_char_p)
2738        self.lib.carla_rename_plugin.restype = c_bool
2739
2740        self.lib.carla_clone_plugin.argtypes = (c_void_p, c_uint)
2741        self.lib.carla_clone_plugin.restype = c_bool
2742
2743        self.lib.carla_replace_plugin.argtypes = (c_void_p, c_uint)
2744        self.lib.carla_replace_plugin.restype = c_bool
2745
2746        self.lib.carla_switch_plugins.argtypes = (c_void_p, c_uint, c_uint)
2747        self.lib.carla_switch_plugins.restype = c_bool
2748
2749        self.lib.carla_load_plugin_state.argtypes = (c_void_p, c_uint, c_char_p)
2750        self.lib.carla_load_plugin_state.restype = c_bool
2751
2752        self.lib.carla_save_plugin_state.argtypes = (c_void_p, c_uint, c_char_p)
2753        self.lib.carla_save_plugin_state.restype = c_bool
2754
2755        self.lib.carla_export_plugin_lv2.argtypes = (c_void_p, c_uint, c_char_p)
2756        self.lib.carla_export_plugin_lv2.restype = c_bool
2757
2758        self.lib.carla_get_plugin_info.argtypes = (c_void_p, c_uint)
2759        self.lib.carla_get_plugin_info.restype = POINTER(CarlaPluginInfo)
2760
2761        self.lib.carla_get_audio_port_count_info.argtypes = (c_void_p, c_uint)
2762        self.lib.carla_get_audio_port_count_info.restype = POINTER(CarlaPortCountInfo)
2763
2764        self.lib.carla_get_midi_port_count_info.argtypes = (c_void_p, c_uint)
2765        self.lib.carla_get_midi_port_count_info.restype = POINTER(CarlaPortCountInfo)
2766
2767        self.lib.carla_get_parameter_count_info.argtypes = (c_void_p, c_uint)
2768        self.lib.carla_get_parameter_count_info.restype = POINTER(CarlaPortCountInfo)
2769
2770        self.lib.carla_get_parameter_info.argtypes = (c_void_p, c_uint, c_uint32)
2771        self.lib.carla_get_parameter_info.restype = POINTER(CarlaParameterInfo)
2772
2773        self.lib.carla_get_parameter_scalepoint_info.argtypes = (c_void_p, c_uint, c_uint32, c_uint32)
2774        self.lib.carla_get_parameter_scalepoint_info.restype = POINTER(CarlaScalePointInfo)
2775
2776        self.lib.carla_get_parameter_data.argtypes = (c_void_p, c_uint, c_uint32)
2777        self.lib.carla_get_parameter_data.restype = POINTER(ParameterData)
2778
2779        self.lib.carla_get_parameter_ranges.argtypes = (c_void_p, c_uint, c_uint32)
2780        self.lib.carla_get_parameter_ranges.restype = POINTER(ParameterRanges)
2781
2782        self.lib.carla_get_midi_program_data.argtypes = (c_void_p, c_uint, c_uint32)
2783        self.lib.carla_get_midi_program_data.restype = POINTER(MidiProgramData)
2784
2785        self.lib.carla_get_custom_data.argtypes = (c_void_p, c_uint, c_uint32)
2786        self.lib.carla_get_custom_data.restype = POINTER(CustomData)
2787
2788        self.lib.carla_get_custom_data_value.argtypes = (c_void_p, c_uint, c_char_p, c_char_p)
2789        self.lib.carla_get_custom_data_value.restype = c_char_p
2790
2791        self.lib.carla_get_chunk_data.argtypes = (c_void_p, c_uint)
2792        self.lib.carla_get_chunk_data.restype = c_char_p
2793
2794        self.lib.carla_get_parameter_count.argtypes = (c_void_p, c_uint)
2795        self.lib.carla_get_parameter_count.restype = c_uint32
2796
2797        self.lib.carla_get_program_count.argtypes = (c_void_p, c_uint)
2798        self.lib.carla_get_program_count.restype = c_uint32
2799
2800        self.lib.carla_get_midi_program_count.argtypes = (c_void_p, c_uint)
2801        self.lib.carla_get_midi_program_count.restype = c_uint32
2802
2803        self.lib.carla_get_custom_data_count.argtypes = (c_void_p, c_uint)
2804        self.lib.carla_get_custom_data_count.restype = c_uint32
2805
2806        self.lib.carla_get_parameter_text.argtypes = (c_void_p, c_uint, c_uint32)
2807        self.lib.carla_get_parameter_text.restype = c_char_p
2808
2809        self.lib.carla_get_program_name.argtypes = (c_void_p, c_uint, c_uint32)
2810        self.lib.carla_get_program_name.restype = c_char_p
2811
2812        self.lib.carla_get_midi_program_name.argtypes = (c_void_p, c_uint, c_uint32)
2813        self.lib.carla_get_midi_program_name.restype = c_char_p
2814
2815        self.lib.carla_get_real_plugin_name.argtypes = (c_void_p, c_uint)
2816        self.lib.carla_get_real_plugin_name.restype = c_char_p
2817
2818        self.lib.carla_get_current_program_index.argtypes = (c_void_p, c_uint)
2819        self.lib.carla_get_current_program_index.restype = c_int32
2820
2821        self.lib.carla_get_current_midi_program_index.argtypes = (c_void_p, c_uint)
2822        self.lib.carla_get_current_midi_program_index.restype = c_int32
2823
2824        self.lib.carla_get_default_parameter_value.argtypes = (c_void_p, c_uint, c_uint32)
2825        self.lib.carla_get_default_parameter_value.restype = c_float
2826
2827        self.lib.carla_get_current_parameter_value.argtypes = (c_void_p, c_uint, c_uint32)
2828        self.lib.carla_get_current_parameter_value.restype = c_float
2829
2830        self.lib.carla_get_internal_parameter_value.argtypes = (c_void_p, c_uint, c_int32)
2831        self.lib.carla_get_internal_parameter_value.restype = c_float
2832
2833        self.lib.carla_get_input_peak_value.argtypes = (c_void_p, c_uint, c_bool)
2834        self.lib.carla_get_input_peak_value.restype = c_float
2835
2836        self.lib.carla_get_output_peak_value.argtypes = (c_void_p, c_uint, c_bool)
2837        self.lib.carla_get_output_peak_value.restype = c_float
2838
2839        self.lib.carla_render_inline_display.argtypes = (c_void_p, c_uint, c_uint, c_uint)
2840        self.lib.carla_render_inline_display.restype = POINTER(CarlaInlineDisplayImageSurface)
2841
2842        self.lib.carla_set_option.argtypes = (c_void_p, c_uint, c_uint, c_bool)
2843        self.lib.carla_set_option.restype = None
2844
2845        self.lib.carla_set_active.argtypes = (c_void_p, c_uint, c_bool)
2846        self.lib.carla_set_active.restype = None
2847
2848        self.lib.carla_set_drywet.argtypes = (c_void_p, c_uint, c_float)
2849        self.lib.carla_set_drywet.restype = None
2850
2851        self.lib.carla_set_volume.argtypes = (c_void_p, c_uint, c_float)
2852        self.lib.carla_set_volume.restype = None
2853
2854        self.lib.carla_set_balance_left.argtypes = (c_void_p, c_uint, c_float)
2855        self.lib.carla_set_balance_left.restype = None
2856
2857        self.lib.carla_set_balance_right.argtypes = (c_void_p, c_uint, c_float)
2858        self.lib.carla_set_balance_right.restype = None
2859
2860        self.lib.carla_set_panning.argtypes = (c_void_p, c_uint, c_float)
2861        self.lib.carla_set_panning.restype = None
2862
2863        self.lib.carla_set_ctrl_channel.argtypes = (c_void_p, c_uint, c_int8)
2864        self.lib.carla_set_ctrl_channel.restype = None
2865
2866        self.lib.carla_set_parameter_value.argtypes = (c_void_p, c_uint, c_uint32, c_float)
2867        self.lib.carla_set_parameter_value.restype = None
2868
2869        self.lib.carla_set_parameter_midi_channel.argtypes = (c_void_p, c_uint, c_uint32, c_uint8)
2870        self.lib.carla_set_parameter_midi_channel.restype = None
2871
2872        self.lib.carla_set_parameter_mapped_control_index.argtypes = (c_void_p, c_uint, c_uint32, c_int16)
2873        self.lib.carla_set_parameter_mapped_control_index.restype = None
2874
2875        self.lib.carla_set_parameter_mapped_range.argtypes = (c_void_p, c_uint, c_uint32, c_float, c_float)
2876        self.lib.carla_set_parameter_mapped_range.restype = None
2877
2878        self.lib.carla_set_parameter_touch.argtypes = (c_void_p, c_uint, c_uint32, c_bool)
2879        self.lib.carla_set_parameter_touch.restype = None
2880
2881        self.lib.carla_set_program.argtypes = (c_void_p, c_uint, c_uint32)
2882        self.lib.carla_set_program.restype = None
2883
2884        self.lib.carla_set_midi_program.argtypes = (c_void_p, c_uint, c_uint32)
2885        self.lib.carla_set_midi_program.restype = None
2886
2887        self.lib.carla_set_custom_data.argtypes = (c_void_p, c_uint, c_char_p, c_char_p, c_char_p)
2888        self.lib.carla_set_custom_data.restype = None
2889
2890        self.lib.carla_set_chunk_data.argtypes = (c_void_p, c_uint, c_char_p)
2891        self.lib.carla_set_chunk_data.restype = None
2892
2893        self.lib.carla_prepare_for_save.argtypes = (c_void_p, c_uint)
2894        self.lib.carla_prepare_for_save.restype = None
2895
2896        self.lib.carla_reset_parameters.argtypes = (c_void_p, c_uint)
2897        self.lib.carla_reset_parameters.restype = None
2898
2899        self.lib.carla_randomize_parameters.argtypes = (c_void_p, c_uint)
2900        self.lib.carla_randomize_parameters.restype = None
2901
2902        self.lib.carla_send_midi_note.argtypes = (c_void_p, c_uint, c_uint8, c_uint8, c_uint8)
2903        self.lib.carla_send_midi_note.restype = None
2904
2905        self.lib.carla_show_custom_ui.argtypes = (c_void_p, c_uint, c_bool)
2906        self.lib.carla_show_custom_ui.restype = None
2907
2908        self.lib.carla_get_buffer_size.argtypes = (c_void_p,)
2909        self.lib.carla_get_buffer_size.restype = c_uint32
2910
2911        self.lib.carla_get_sample_rate.argtypes = (c_void_p,)
2912        self.lib.carla_get_sample_rate.restype = c_double
2913
2914        self.lib.carla_get_last_error.argtypes = (c_void_p,)
2915        self.lib.carla_get_last_error.restype = c_char_p
2916
2917        self.lib.carla_get_host_osc_url_tcp.argtypes = (c_void_p,)
2918        self.lib.carla_get_host_osc_url_tcp.restype = c_char_p
2919
2920        self.lib.carla_get_host_osc_url_udp.argtypes = (c_void_p,)
2921        self.lib.carla_get_host_osc_url_udp.restype = c_char_p
2922
2923        self.lib.carla_nsm_init.argtypes = (c_void_p, c_uint64, c_char_p)
2924        self.lib.carla_nsm_init.restype = c_bool
2925
2926        self.lib.carla_nsm_ready.argtypes = (c_void_p, c_int)
2927        self.lib.carla_nsm_ready.restype = None
2928
2929        self.handle = self.lib.carla_standalone_host_init()
2930
2931        self._engineCallback = None
2932        self._fileCallback = None
2933
2934    # --------------------------------------------------------------------------------------------------------
2935
2936    def get_engine_driver_count(self):
2937        return int(self.lib.carla_get_engine_driver_count())
2938
2939    def get_engine_driver_name(self, index):
2940        return charPtrToString(self.lib.carla_get_engine_driver_name(index))
2941
2942    def get_engine_driver_device_names(self, index):
2943        return charPtrPtrToStringList(self.lib.carla_get_engine_driver_device_names(index))
2944
2945    def get_engine_driver_device_info(self, index, name):
2946        return structToDict(self.lib.carla_get_engine_driver_device_info(index, name.encode("utf-8")).contents)
2947
2948    def show_engine_driver_device_control_panel(self, index, name):
2949        return bool(self.lib.carla_show_engine_driver_device_control_panel(index, name.encode("utf-8")))
2950
2951    def engine_init(self, driverName, clientName):
2952        return bool(self.lib.carla_engine_init(self.handle, driverName.encode("utf-8"), clientName.encode("utf-8")))
2953
2954    def engine_close(self):
2955        return bool(self.lib.carla_engine_close(self.handle))
2956
2957    def engine_idle(self):
2958        self.lib.carla_engine_idle(self.handle)
2959
2960    def is_engine_running(self):
2961        return bool(self.lib.carla_is_engine_running(self.handle))
2962
2963    def get_runtime_engine_info(self):
2964        return structToDict(self.lib.carla_get_runtime_engine_info(self.handle).contents)
2965
2966    def get_runtime_engine_driver_device_info(self):
2967        return structToDict(self.lib.carla_get_runtime_engine_driver_device_info(self.handle).contents)
2968
2969    def set_engine_buffer_size_and_sample_rate(self, bufferSize, sampleRate):
2970        return bool(self.lib.carla_set_engine_buffer_size_and_sample_rate(self.handle, bufferSize, sampleRate))
2971
2972    def show_engine_device_control_panel(self):
2973        return bool(self.lib.carla_show_engine_device_control_panel(self.handle))
2974
2975    def clear_engine_xruns(self):
2976        self.lib.carla_clear_engine_xruns(self.handle)
2977
2978    def cancel_engine_action(self):
2979        self.lib.carla_cancel_engine_action(self.handle)
2980
2981    def set_engine_about_to_close(self):
2982        return bool(self.lib.carla_set_engine_about_to_close(self.handle))
2983
2984    def set_engine_callback(self, func):
2985        self._engineCallback = EngineCallbackFunc(func)
2986        self.lib.carla_set_engine_callback(self.handle, self._engineCallback, None)
2987
2988    def set_engine_option(self, option, value, valueStr):
2989        self.lib.carla_set_engine_option(self.handle, option, value, valueStr.encode("utf-8"))
2990
2991    def set_file_callback(self, func):
2992        self._fileCallback = FileCallbackFunc(func)
2993        self.lib.carla_set_file_callback(self.handle, self._fileCallback, None)
2994
2995    def load_file(self, filename):
2996        return bool(self.lib.carla_load_file(self.handle, filename.encode("utf-8")))
2997
2998    def load_project(self, filename):
2999        return bool(self.lib.carla_load_project(self.handle, filename.encode("utf-8")))
3000
3001    def save_project(self, filename):
3002        return bool(self.lib.carla_save_project(self.handle, filename.encode("utf-8")))
3003
3004    def clear_project_filename(self):
3005        self.lib.carla_clear_project_filename(self.handle)
3006
3007    def patchbay_connect(self, external, groupIdA, portIdA, groupIdB, portIdB):
3008        return bool(self.lib.carla_patchbay_connect(self.handle, external, groupIdA, portIdA, groupIdB, portIdB))
3009
3010    def patchbay_disconnect(self, external, connectionId):
3011        return bool(self.lib.carla_patchbay_disconnect(self.handle, external, connectionId))
3012
3013    def patchbay_set_group_pos(self, external, groupId, x1, y1, x2, y2):
3014        return bool(self.lib.carla_patchbay_set_group_pos(self.handle, external, groupId, x1, y1, x2, y2))
3015
3016    def patchbay_refresh(self, external):
3017        return bool(self.lib.carla_patchbay_refresh(self.handle, external))
3018
3019    def transport_play(self):
3020        self.lib.carla_transport_play(self.handle)
3021
3022    def transport_pause(self):
3023        self.lib.carla_transport_pause(self.handle)
3024
3025    def transport_bpm(self, bpm):
3026        self.lib.carla_transport_bpm(self.handle, bpm)
3027
3028    def transport_relocate(self, frame):
3029        self.lib.carla_transport_relocate(self.handle, frame)
3030
3031    def get_current_transport_frame(self):
3032        return int(self.lib.carla_get_current_transport_frame(self.handle))
3033
3034    def get_transport_info(self):
3035        return structToDict(self.lib.carla_get_transport_info(self.handle).contents)
3036
3037    def get_current_plugin_count(self):
3038        return int(self.lib.carla_get_current_plugin_count(self.handle))
3039
3040    def get_max_plugin_number(self):
3041        return int(self.lib.carla_get_max_plugin_number(self.handle))
3042
3043    def add_plugin(self, btype, ptype, filename, name, label, uniqueId, extraPtr, options):
3044        cfilename = filename.encode("utf-8") if filename else None
3045        cname     = name.encode("utf-8") if name else None
3046        if ptype == PLUGIN_JACK:
3047            clabel = bytes(ord(b) for b in label)
3048        else:
3049            clabel = label.encode("utf-8") if label else None
3050        return bool(self.lib.carla_add_plugin(self.handle,
3051                                              btype, ptype,
3052                                              cfilename, cname, clabel, uniqueId, cast(extraPtr, c_void_p), options))
3053
3054    def remove_plugin(self, pluginId):
3055        return bool(self.lib.carla_remove_plugin(self.handle, pluginId))
3056
3057    def remove_all_plugins(self):
3058        return bool(self.lib.carla_remove_all_plugins(self.handle))
3059
3060    def rename_plugin(self, pluginId, newName):
3061        return bool(self.lib.carla_rename_plugin(self.handle, pluginId, newName.encode("utf-8")))
3062
3063    def clone_plugin(self, pluginId):
3064        return bool(self.lib.carla_clone_plugin(self.handle, pluginId))
3065
3066    def replace_plugin(self, pluginId):
3067        return bool(self.lib.carla_replace_plugin(self.handle, pluginId))
3068
3069    def switch_plugins(self, pluginIdA, pluginIdB):
3070        return bool(self.lib.carla_switch_plugins(self.handle, pluginIdA, pluginIdB))
3071
3072    def load_plugin_state(self, pluginId, filename):
3073        return bool(self.lib.carla_load_plugin_state(self.handle, pluginId, filename.encode("utf-8")))
3074
3075    def save_plugin_state(self, pluginId, filename):
3076        return bool(self.lib.carla_save_plugin_state(self.handle, pluginId, filename.encode("utf-8")))
3077
3078    def export_plugin_lv2(self, pluginId, lv2path):
3079        return bool(self.lib.carla_export_plugin_lv2(self.handle, pluginId, lv2path.encode("utf-8")))
3080
3081    def get_plugin_info(self, pluginId):
3082        return structToDict(self.lib.carla_get_plugin_info(self.handle, pluginId).contents)
3083
3084    def get_audio_port_count_info(self, pluginId):
3085        return structToDict(self.lib.carla_get_audio_port_count_info(self.handle, pluginId).contents)
3086
3087    def get_midi_port_count_info(self, pluginId):
3088        return structToDict(self.lib.carla_get_midi_port_count_info(self.handle, pluginId).contents)
3089
3090    def get_parameter_count_info(self, pluginId):
3091        return structToDict(self.lib.carla_get_parameter_count_info(self.handle, pluginId).contents)
3092
3093    def get_parameter_info(self, pluginId, parameterId):
3094        return structToDict(self.lib.carla_get_parameter_info(self.handle, pluginId, parameterId).contents)
3095
3096    def get_parameter_scalepoint_info(self, pluginId, parameterId, scalePointId):
3097        return structToDict(self.lib.carla_get_parameter_scalepoint_info(self.handle,
3098                                                                         pluginId,
3099                                                                         parameterId,
3100                                                                         scalePointId).contents)
3101
3102    def get_parameter_data(self, pluginId, parameterId):
3103        return structToDict(self.lib.carla_get_parameter_data(self.handle, pluginId, parameterId).contents)
3104
3105    def get_parameter_ranges(self, pluginId, parameterId):
3106        return structToDict(self.lib.carla_get_parameter_ranges(self.handle, pluginId, parameterId).contents)
3107
3108    def get_midi_program_data(self, pluginId, midiProgramId):
3109        return structToDict(self.lib.carla_get_midi_program_data(self.handle, pluginId, midiProgramId).contents)
3110
3111    def get_custom_data(self, pluginId, customDataId):
3112        return structToDict(self.lib.carla_get_custom_data(self.handle, pluginId, customDataId).contents)
3113
3114    def get_custom_data_value(self, pluginId, type_, key):
3115        return charPtrToString(self.lib.carla_get_custom_data_value(self.handle,
3116                                                                    pluginId,
3117                                                                    type_.encode("utf-8"),
3118                                                                    key.encode("utf-8")))
3119
3120    def get_chunk_data(self, pluginId):
3121        return charPtrToString(self.lib.carla_get_chunk_data(self.handle, pluginId))
3122
3123    def get_parameter_count(self, pluginId):
3124        return int(self.lib.carla_get_parameter_count(self.handle, pluginId))
3125
3126    def get_program_count(self, pluginId):
3127        return int(self.lib.carla_get_program_count(self.handle, pluginId))
3128
3129    def get_midi_program_count(self, pluginId):
3130        return int(self.lib.carla_get_midi_program_count(self.handle, pluginId))
3131
3132    def get_custom_data_count(self, pluginId):
3133        return int(self.lib.carla_get_custom_data_count(self.handle, pluginId))
3134
3135    def get_parameter_text(self, pluginId, parameterId):
3136        return charPtrToString(self.lib.carla_get_parameter_text(self.handle, pluginId, parameterId))
3137
3138    def get_program_name(self, pluginId, programId):
3139        return charPtrToString(self.lib.carla_get_program_name(self.handle, pluginId, programId))
3140
3141    def get_midi_program_name(self, pluginId, midiProgramId):
3142        return charPtrToString(self.lib.carla_get_midi_program_name(self.handle, pluginId, midiProgramId))
3143
3144    def get_real_plugin_name(self, pluginId):
3145        return charPtrToString(self.lib.carla_get_real_plugin_name(self.handle, pluginId))
3146
3147    def get_current_program_index(self, pluginId):
3148        return int(self.lib.carla_get_current_program_index(self.handle, pluginId))
3149
3150    def get_current_midi_program_index(self, pluginId):
3151        return int(self.lib.carla_get_current_midi_program_index(self.handle, pluginId))
3152
3153    def get_default_parameter_value(self, pluginId, parameterId):
3154        return float(self.lib.carla_get_default_parameter_value(self.handle, pluginId, parameterId))
3155
3156    def get_current_parameter_value(self, pluginId, parameterId):
3157        return float(self.lib.carla_get_current_parameter_value(self.handle, pluginId, parameterId))
3158
3159    def get_internal_parameter_value(self, pluginId, parameterId):
3160        return float(self.lib.carla_get_internal_parameter_value(self.handle, pluginId, parameterId))
3161
3162    def get_input_peak_value(self, pluginId, isLeft):
3163        return float(self.lib.carla_get_input_peak_value(self.handle, pluginId, isLeft))
3164
3165    def get_output_peak_value(self, pluginId, isLeft):
3166        return float(self.lib.carla_get_output_peak_value(self.handle, pluginId, isLeft))
3167
3168    def render_inline_display(self, pluginId, width, height):
3169        ptr = self.lib.carla_render_inline_display(self.handle, pluginId, width, height)
3170        if not ptr or not ptr.contents:
3171            return None
3172        contents = ptr.contents
3173        datalen = contents.height * contents.stride
3174        databuf = pack("%iB" % datalen, *contents.data[:datalen])
3175        data = {
3176            'data': databuf,
3177            'width': contents.width,
3178            'height': contents.height,
3179            'stride': contents.stride,
3180        }
3181        return data
3182
3183    def set_option(self, pluginId, option, yesNo):
3184        self.lib.carla_set_option(self.handle, pluginId, option, yesNo)
3185
3186    def set_active(self, pluginId, onOff):
3187        self.lib.carla_set_active(self.handle, pluginId, onOff)
3188
3189    def set_drywet(self, pluginId, value):
3190        self.lib.carla_set_drywet(self.handle, pluginId, value)
3191
3192    def set_volume(self, pluginId, value):
3193        self.lib.carla_set_volume(self.handle, pluginId, value)
3194
3195    def set_balance_left(self, pluginId, value):
3196        self.lib.carla_set_balance_left(self.handle, pluginId, value)
3197
3198    def set_balance_right(self, pluginId, value):
3199        self.lib.carla_set_balance_right(self.handle, pluginId, value)
3200
3201    def set_panning(self, pluginId, value):
3202        self.lib.carla_set_panning(self.handle, pluginId, value)
3203
3204    def set_ctrl_channel(self, pluginId, channel):
3205        self.lib.carla_set_ctrl_channel(self.handle, pluginId, channel)
3206
3207    def set_parameter_value(self, pluginId, parameterId, value):
3208        self.lib.carla_set_parameter_value(self.handle, pluginId, parameterId, value)
3209
3210    def set_parameter_midi_channel(self, pluginId, parameterId, channel):
3211        self.lib.carla_set_parameter_midi_channel(self.handle, pluginId, parameterId, channel)
3212
3213    def set_parameter_mapped_control_index(self, pluginId, parameterId, index):
3214        self.lib.carla_set_parameter_mapped_control_index(self.handle, pluginId, parameterId, index)
3215
3216    def set_parameter_mapped_range(self, pluginId, parameterId, minimum, maximum):
3217        self.lib.carla_set_parameter_mapped_range(self.handle, pluginId, parameterId, minimum, maximum)
3218
3219    def set_parameter_touch(self, pluginId, parameterId, touch):
3220        self.lib.carla_set_parameter_touch(self.handle, pluginId, parameterId, touch)
3221
3222    def set_program(self, pluginId, programId):
3223        self.lib.carla_set_program(self.handle, pluginId, programId)
3224
3225    def set_midi_program(self, pluginId, midiProgramId):
3226        self.lib.carla_set_midi_program(self.handle, pluginId, midiProgramId)
3227
3228    def set_custom_data(self, pluginId, type_, key, value):
3229        self.lib.carla_set_custom_data(self.handle,
3230                                       pluginId,
3231                                       type_.encode("utf-8"),
3232                                       key.encode("utf-8"),
3233                                       value.encode("utf-8"))
3234
3235    def set_chunk_data(self, pluginId, chunkData):
3236        self.lib.carla_set_chunk_data(self.handle, pluginId, chunkData.encode("utf-8"))
3237
3238    def prepare_for_save(self, pluginId):
3239        self.lib.carla_prepare_for_save(self.handle, pluginId)
3240
3241    def reset_parameters(self, pluginId):
3242        self.lib.carla_reset_parameters(self.handle, pluginId)
3243
3244    def randomize_parameters(self, pluginId):
3245        self.lib.carla_randomize_parameters(self.handle, pluginId)
3246
3247    def send_midi_note(self, pluginId, channel, note, velocity):
3248        self.lib.carla_send_midi_note(self.handle, pluginId, channel, note, velocity)
3249
3250    def show_custom_ui(self, pluginId, yesNo):
3251        self.lib.carla_show_custom_ui(self.handle, pluginId, yesNo)
3252
3253    def get_buffer_size(self):
3254        return int(self.lib.carla_get_buffer_size(self.handle))
3255
3256    def get_sample_rate(self):
3257        return float(self.lib.carla_get_sample_rate(self.handle))
3258
3259    def get_last_error(self):
3260        return charPtrToString(self.lib.carla_get_last_error(self.handle))
3261
3262    def get_host_osc_url_tcp(self):
3263        return charPtrToString(self.lib.carla_get_host_osc_url_tcp(self.handle))
3264
3265    def get_host_osc_url_udp(self):
3266        return charPtrToString(self.lib.carla_get_host_osc_url_udp(self.handle))
3267
3268    def nsm_init(self, pid, executableName):
3269        return bool(self.lib.carla_nsm_init(self.handle, pid, executableName.encode("utf-8")))
3270
3271    def nsm_ready(self, opcode):
3272        self.lib.carla_nsm_ready(self.handle, opcode)
3273
3274# ---------------------------------------------------------------------------------------------------------------------
3275# Helper object for CarlaHostPlugin
3276
3277class PluginStoreInfo():
3278    def __init__(self):
3279        self.clear()
3280
3281    def clear(self):
3282        self.pluginInfo     = PyCarlaPluginInfo.copy()
3283        self.pluginRealName = ""
3284        self.internalValues = [0.0, 1.0, 1.0, -1.0, 1.0, 0.0, -1.0]
3285        self.audioCountInfo = PyCarlaPortCountInfo.copy()
3286        self.midiCountInfo  = PyCarlaPortCountInfo.copy()
3287        self.parameterCount = 0
3288        self.parameterCountInfo = PyCarlaPortCountInfo.copy()
3289        self.parameterInfo   = []
3290        self.parameterData   = []
3291        self.parameterRanges = []
3292        self.parameterValues = []
3293        self.programCount   = 0
3294        self.programCurrent = -1
3295        self.programNames   = []
3296        self.midiProgramCount   = 0
3297        self.midiProgramCurrent = -1
3298        self.midiProgramData    = []
3299        self.customDataCount = 0
3300        self.customData      = []
3301        self.peaks = [0.0, 0.0, 0.0, 0.0]
3302
3303# ---------------------------------------------------------------------------------------------------------------------
3304# Carla Host object for plugins (using pipes)
3305
3306class CarlaHostPlugin(CarlaHostMeta):
3307    def __init__(self):
3308        CarlaHostMeta.__init__(self)
3309
3310        # info about this host object
3311        self.isPlugin          = True
3312        self.processModeForced = True
3313
3314        # text data to return when requested
3315        self.fMaxPluginNumber = 0
3316        self.fLastError       = ""
3317
3318        # plugin info
3319        self.fPluginsInfo = {}
3320        self.fFallbackPluginInfo = PluginStoreInfo()
3321
3322        # runtime engine info
3323        self.fRuntimeEngineInfo = {
3324            "load": 0.0,
3325            "xruns": 0
3326        }
3327
3328        # transport info
3329        self.fTransportInfo = {
3330            "playing": False,
3331            "frame": 0,
3332            "bar": 0,
3333            "beat": 0,
3334            "tick": 0,
3335            "bpm": 0.0
3336        }
3337
3338        # some other vars
3339        self.fBufferSize = 0
3340        self.fSampleRate = 0.0
3341        self.fOscTCP = ""
3342        self.fOscUDP = ""
3343
3344    # --------------------------------------------------------------------------------------------------------
3345
3346    # Needs to be reimplemented
3347    @abstractmethod
3348    def sendMsg(self, lines):
3349        raise NotImplementedError
3350
3351    # internal, sets error if sendMsg failed
3352    def sendMsgAndSetError(self, lines):
3353        if self.sendMsg(lines):
3354            return True
3355
3356        self.fLastError = "Communication error with backend"
3357        return False
3358
3359    # --------------------------------------------------------------------------------------------------------
3360
3361    def get_engine_driver_count(self):
3362        return 1
3363
3364    def get_engine_driver_name(self, index):
3365        return "Plugin"
3366
3367    def get_engine_driver_device_names(self, index):
3368        return []
3369
3370    def get_engine_driver_device_info(self, index, name):
3371        return PyEngineDriverDeviceInfo
3372
3373    def show_engine_driver_device_control_panel(self, index, name):
3374        return False
3375
3376    def get_runtime_engine_info(self):
3377        return self.fRuntimeEngineInfo
3378
3379    def get_runtime_engine_driver_device_info(self):
3380        return PyCarlaRuntimeEngineDriverDeviceInfo
3381
3382    def set_engine_buffer_size_and_sample_rate(self, bufferSize, sampleRate):
3383        return False
3384
3385    def show_engine_device_control_panel(self):
3386        return False
3387
3388    def clear_engine_xruns(self):
3389        self.sendMsg(["clear_engine_xruns"])
3390
3391    def cancel_engine_action(self):
3392        self.sendMsg(["cancel_engine_action"])
3393
3394    def set_engine_callback(self, func):
3395        return # TODO
3396
3397    def set_engine_option(self, option, value, valueStr):
3398        self.sendMsg(["set_engine_option", option, int(value), valueStr])
3399
3400    def set_file_callback(self, func):
3401        return # TODO
3402
3403    def load_file(self, filename):
3404        return self.sendMsgAndSetError(["load_file", filename])
3405
3406    def load_project(self, filename):
3407        return self.sendMsgAndSetError(["load_project", filename])
3408
3409    def save_project(self, filename):
3410        return self.sendMsgAndSetError(["save_project", filename])
3411
3412    def clear_project_filename(self):
3413        return self.sendMsgAndSetError(["clear_project_filename"])
3414
3415    def patchbay_connect(self, external, groupIdA, portIdA, groupIdB, portIdB):
3416        return self.sendMsgAndSetError(["patchbay_connect", external, groupIdA, portIdA, groupIdB, portIdB])
3417
3418    def patchbay_disconnect(self, external, connectionId):
3419        return self.sendMsgAndSetError(["patchbay_disconnect", external, connectionId])
3420
3421    def patchbay_set_group_pos(self, external, groupId, x1, y1, x2, y2):
3422        return self.sendMsgAndSetError(["patchbay_set_group_pos", external, groupId, x1, y1, x2, y2])
3423
3424    def patchbay_refresh(self, external):
3425        return self.sendMsgAndSetError(["patchbay_refresh", external])
3426
3427    def transport_play(self):
3428        self.sendMsg(["transport_play"])
3429
3430    def transport_pause(self):
3431        self.sendMsg(["transport_pause"])
3432
3433    def transport_bpm(self, bpm):
3434        self.sendMsg(["transport_bpm", bpm])
3435
3436    def transport_relocate(self, frame):
3437        self.sendMsg(["transport_relocate", frame])
3438
3439    def get_current_transport_frame(self):
3440        return self.fTransportInfo['frame']
3441
3442    def get_transport_info(self):
3443        return self.fTransportInfo
3444
3445    def get_current_plugin_count(self):
3446        return len(self.fPluginsInfo)
3447
3448    def get_max_plugin_number(self):
3449        return self.fMaxPluginNumber
3450
3451    def add_plugin(self, btype, ptype, filename, name, label, uniqueId, extraPtr, options):
3452        return self.sendMsgAndSetError(["add_plugin",
3453                                        btype, ptype,
3454                                        filename or "(null)",
3455                                        name or "(null)",
3456                                        label, uniqueId, options])
3457
3458    def remove_plugin(self, pluginId):
3459        return self.sendMsgAndSetError(["remove_plugin", pluginId])
3460
3461    def remove_all_plugins(self):
3462        return self.sendMsgAndSetError(["remove_all_plugins"])
3463
3464    def rename_plugin(self, pluginId, newName):
3465        return self.sendMsgAndSetError(["rename_plugin", pluginId, newName])
3466
3467    def clone_plugin(self, pluginId):
3468        return self.sendMsgAndSetError(["clone_plugin", pluginId])
3469
3470    def replace_plugin(self, pluginId):
3471        return self.sendMsgAndSetError(["replace_plugin", pluginId])
3472
3473    def switch_plugins(self, pluginIdA, pluginIdB):
3474        ret = self.sendMsgAndSetError(["switch_plugins", pluginIdA, pluginIdB])
3475        if ret:
3476            self._switchPlugins(pluginIdA, pluginIdB)
3477        return ret
3478
3479    def load_plugin_state(self, pluginId, filename):
3480        return self.sendMsgAndSetError(["load_plugin_state", pluginId, filename])
3481
3482    def save_plugin_state(self, pluginId, filename):
3483        return self.sendMsgAndSetError(["save_plugin_state", pluginId, filename])
3484
3485    def export_plugin_lv2(self, pluginId, lv2path):
3486        self.fLastError = "Operation unavailable in plugin version"
3487        return False
3488
3489    def get_plugin_info(self, pluginId):
3490        return self.fPluginsInfo.get(pluginId, self.fFallbackPluginInfo).pluginInfo
3491
3492    def get_audio_port_count_info(self, pluginId):
3493        return self.fPluginsInfo.get(pluginId, self.fFallbackPluginInfo).audioCountInfo
3494
3495    def get_midi_port_count_info(self, pluginId):
3496        return self.fPluginsInfo.get(pluginId, self.fFallbackPluginInfo).midiCountInfo
3497
3498    def get_parameter_count_info(self, pluginId):
3499        return self.fPluginsInfo.get(pluginId, self.fFallbackPluginInfo).parameterCountInfo
3500
3501    def get_parameter_info(self, pluginId, parameterId):
3502        return self.fPluginsInfo.get(pluginId, self.fFallbackPluginInfo).parameterInfo[parameterId]
3503
3504    def get_parameter_scalepoint_info(self, pluginId, parameterId, scalePointId):
3505        return PyCarlaScalePointInfo
3506
3507    def get_parameter_data(self, pluginId, parameterId):
3508        return self.fPluginsInfo.get(pluginId, self.fFallbackPluginInfo).parameterData[parameterId]
3509
3510    def get_parameter_ranges(self, pluginId, parameterId):
3511        return self.fPluginsInfo.get(pluginId, self.fFallbackPluginInfo).parameterRanges[parameterId]
3512
3513    def get_midi_program_data(self, pluginId, midiProgramId):
3514        return self.fPluginsInfo.get(pluginId, self.fFallbackPluginInfo).midiProgramData[midiProgramId]
3515
3516    def get_custom_data(self, pluginId, customDataId):
3517        return self.fPluginsInfo.get(pluginId, self.fFallbackPluginInfo).customData[customDataId]
3518
3519    def get_custom_data_value(self, pluginId, type_, key):
3520        plugin = self.fPluginsInfo.get(pluginId, None)
3521        if plugin is None:
3522            return ""
3523        for customData in plugin.customData:
3524            if customData['type'] == type_ and customData['key'] == key:
3525                return customData['value']
3526        return ""
3527
3528    def get_chunk_data(self, pluginId):
3529        return ""
3530
3531    def get_parameter_count(self, pluginId):
3532        return self.fPluginsInfo.get(pluginId, self.fFallbackPluginInfo).parameterCount
3533
3534    def get_program_count(self, pluginId):
3535        return self.fPluginsInfo.get(pluginId, self.fFallbackPluginInfo).programCount
3536
3537    def get_midi_program_count(self, pluginId):
3538        return self.fPluginsInfo.get(pluginId, self.fFallbackPluginInfo).midiProgramCount
3539
3540    def get_custom_data_count(self, pluginId):
3541        return self.fPluginsInfo.get(pluginId, self.fFallbackPluginInfo).customDataCount
3542
3543    def get_parameter_text(self, pluginId, parameterId):
3544        return ""
3545
3546    def get_program_name(self, pluginId, programId):
3547        return self.fPluginsInfo[pluginId].programNames[programId]
3548
3549    def get_midi_program_name(self, pluginId, midiProgramId):
3550        return self.fPluginsInfo[pluginId].midiProgramData[midiProgramId]['label']
3551
3552    def get_real_plugin_name(self, pluginId):
3553        return self.fPluginsInfo.get(pluginId, self.fFallbackPluginInfo).pluginRealName
3554
3555    def get_current_program_index(self, pluginId):
3556        return self.fPluginsInfo.get(pluginId, self.fFallbackPluginInfo).programCurrent
3557
3558    def get_current_midi_program_index(self, pluginId):
3559        return self.fPluginsInfo.get(pluginId, self.fFallbackPluginInfo).midiProgramCurrent
3560
3561    def get_default_parameter_value(self, pluginId, parameterId):
3562        return self.fPluginsInfo[pluginId].parameterRanges[parameterId]['def']
3563
3564    def get_current_parameter_value(self, pluginId, parameterId):
3565        return self.fPluginsInfo[pluginId].parameterValues[parameterId]
3566
3567    def get_internal_parameter_value(self, pluginId, parameterId):
3568        if parameterId == PARAMETER_NULL or parameterId <= PARAMETER_MAX:
3569            return 0.0
3570        if parameterId < 0:
3571            return self.fPluginsInfo[pluginId].internalValues[abs(parameterId)-2]
3572
3573        return self.fPluginsInfo[pluginId].parameterValues[parameterId]
3574
3575    def get_input_peak_value(self, pluginId, isLeft):
3576        return self.fPluginsInfo[pluginId].peaks[0 if isLeft else 1]
3577
3578    def get_output_peak_value(self, pluginId, isLeft):
3579        return self.fPluginsInfo[pluginId].peaks[2 if isLeft else 3]
3580
3581    def render_inline_display(self, pluginId, width, height):
3582        return None
3583
3584    def set_option(self, pluginId, option, yesNo):
3585        self.sendMsg(["set_option", pluginId, option, yesNo])
3586
3587    def set_active(self, pluginId, onOff):
3588        self.sendMsg(["set_active", pluginId, onOff])
3589        self.fPluginsInfo[pluginId].internalValues[0] = 1.0 if onOff else 0.0
3590
3591    def set_drywet(self, pluginId, value):
3592        self.sendMsg(["set_drywet", pluginId, value])
3593        self.fPluginsInfo[pluginId].internalValues[1] = value
3594
3595    def set_volume(self, pluginId, value):
3596        self.sendMsg(["set_volume", pluginId, value])
3597        self.fPluginsInfo[pluginId].internalValues[2] = value
3598
3599    def set_balance_left(self, pluginId, value):
3600        self.sendMsg(["set_balance_left", pluginId, value])
3601        self.fPluginsInfo[pluginId].internalValues[3] = value
3602
3603    def set_balance_right(self, pluginId, value):
3604        self.sendMsg(["set_balance_right", pluginId, value])
3605        self.fPluginsInfo[pluginId].internalValues[4] = value
3606
3607    def set_panning(self, pluginId, value):
3608        self.sendMsg(["set_panning", pluginId, value])
3609        self.fPluginsInfo[pluginId].internalValues[5] = value
3610
3611    def set_ctrl_channel(self, pluginId, channel):
3612        self.sendMsg(["set_ctrl_channel", pluginId, channel])
3613        self.fPluginsInfo[pluginId].internalValues[6] = float(channel)
3614
3615    def set_parameter_value(self, pluginId, parameterId, value):
3616        self.sendMsg(["set_parameter_value", pluginId, parameterId, value])
3617        self.fPluginsInfo[pluginId].parameterValues[parameterId] = value
3618
3619    def set_parameter_midi_channel(self, pluginId, parameterId, channel):
3620        self.sendMsg(["set_parameter_midi_channel", pluginId, parameterId, channel])
3621        self.fPluginsInfo[pluginId].parameterData[parameterId]['midiChannel'] = channel
3622
3623    def set_parameter_mapped_control_index(self, pluginId, parameterId, index):
3624        self.sendMsg(["set_parameter_mapped_control_index", pluginId, parameterId, index])
3625        self.fPluginsInfo[pluginId].parameterData[parameterId]['mappedControlIndex'] = index
3626
3627    def set_parameter_mapped_range(self, pluginId, parameterId, minimum, maximum):
3628        self.sendMsg(["set_parameter_mapped_range", pluginId, parameterId, minimum, maximum])
3629        self.fPluginsInfo[pluginId].parameterData[parameterId]['mappedMinimum'] = minimum
3630        self.fPluginsInfo[pluginId].parameterData[parameterId]['mappedMaximum'] = maximum
3631
3632    def set_parameter_touch(self, pluginId, parameterId, touch):
3633        self.sendMsg(["set_parameter_touch", pluginId, parameterId, touch])
3634
3635    def set_program(self, pluginId, programId):
3636        self.sendMsg(["set_program", pluginId, programId])
3637        self.fPluginsInfo[pluginId].programCurrent = programId
3638
3639    def set_midi_program(self, pluginId, midiProgramId):
3640        self.sendMsg(["set_midi_program", pluginId, midiProgramId])
3641        self.fPluginsInfo[pluginId].midiProgramCurrent = midiProgramId
3642
3643    def set_custom_data(self, pluginId, type_, key, value):
3644        self.sendMsg(["set_custom_data", pluginId, type_, key, value])
3645
3646        for cdata in self.fPluginsInfo[pluginId].customData:
3647            if cdata['type'] != type_:
3648                continue
3649            if cdata['key'] != key:
3650                continue
3651            cdata['value'] = value
3652            break
3653
3654    def set_chunk_data(self, pluginId, chunkData):
3655        self.sendMsg(["set_chunk_data", pluginId, chunkData])
3656
3657    def prepare_for_save(self, pluginId):
3658        self.sendMsg(["prepare_for_save", pluginId])
3659
3660    def reset_parameters(self, pluginId):
3661        self.sendMsg(["reset_parameters", pluginId])
3662
3663    def randomize_parameters(self, pluginId):
3664        self.sendMsg(["randomize_parameters", pluginId])
3665
3666    def send_midi_note(self, pluginId, channel, note, velocity):
3667        self.sendMsg(["send_midi_note", pluginId, channel, note, velocity])
3668
3669    def show_custom_ui(self, pluginId, yesNo):
3670        self.sendMsg(["show_custom_ui", pluginId, yesNo])
3671
3672    def get_buffer_size(self):
3673        return self.fBufferSize
3674
3675    def get_sample_rate(self):
3676        return self.fSampleRate
3677
3678    def get_last_error(self):
3679        return self.fLastError
3680
3681    def get_host_osc_url_tcp(self):
3682        return self.fOscTCP
3683
3684    def get_host_osc_url_udp(self):
3685        return self.fOscUDP
3686
3687    # --------------------------------------------------------------------------------------------------------
3688
3689    def _set_runtime_info(self, load, xruns):
3690        self.fRuntimeEngineInfo = {
3691            "load": load,
3692            "xruns": xruns
3693        }
3694
3695    def _set_transport(self, playing, frame, bar, beat, tick, bpm):
3696        self.fTransportInfo = {
3697            "playing": playing,
3698            "frame": frame,
3699            "bar": bar,
3700            "beat": beat,
3701            "tick": tick,
3702            "bpm": bpm
3703        }
3704
3705    def _add(self, pluginId):
3706        self.fPluginsInfo[pluginId] = PluginStoreInfo()
3707
3708    def _reset(self, maxPluginId):
3709        self.fPluginsInfo = {}
3710        for i in range(maxPluginId):
3711            self.fPluginsInfo[i] = PluginStoreInfo()
3712
3713    def _allocateAsNeeded(self, pluginId):
3714        if pluginId < len(self.fPluginsInfo):
3715            return
3716
3717        for pid in range(len(self.fPluginsInfo), pluginId+1):
3718            self.fPluginsInfo[pid] = PluginStoreInfo()
3719
3720    def _set_pluginInfo(self, pluginId, info):
3721        plugin = self.fPluginsInfo.get(pluginId, None)
3722        if plugin is None:
3723            print("_set_pluginInfo failed for", pluginId)
3724            return
3725        plugin.pluginInfo = info
3726
3727    def _set_pluginInfoUpdate(self, pluginId, info):
3728        plugin = self.fPluginsInfo.get(pluginId, None)
3729        if plugin is None:
3730            print("_set_pluginInfoUpdate failed for", pluginId)
3731            return
3732        plugin.pluginInfo.update(info)
3733
3734    def _set_pluginName(self, pluginId, name):
3735        plugin = self.fPluginsInfo.get(pluginId, None)
3736        if plugin is None:
3737            print("_set_pluginName failed for", pluginId)
3738            return
3739        plugin.pluginInfo['name'] = name
3740
3741    def _set_pluginRealName(self, pluginId, realName):
3742        plugin = self.fPluginsInfo.get(pluginId, None)
3743        if plugin is None:
3744            print("_set_pluginRealName failed for", pluginId)
3745            return
3746        plugin.pluginRealName = realName
3747
3748    def _set_internalValue(self, pluginId, paramIndex, value):
3749        pluginInfo = self.fPluginsInfo.get(pluginId, None)
3750        if pluginInfo is None:
3751            print("_set_internalValue failed for", pluginId)
3752            return
3753        if PARAMETER_NULL > paramIndex > PARAMETER_MAX:
3754            pluginInfo.internalValues[abs(paramIndex)-2] = float(value)
3755        else:
3756            print("_set_internalValue failed for", pluginId, "with param", paramIndex)
3757
3758    def _set_audioCountInfo(self, pluginId, info):
3759        plugin = self.fPluginsInfo.get(pluginId, None)
3760        if plugin is None:
3761            print("_set_audioCountInfo failed for", pluginId)
3762            return
3763        plugin.audioCountInfo = info
3764
3765    def _set_midiCountInfo(self, pluginId, info):
3766        plugin = self.fPluginsInfo.get(pluginId, None)
3767        if plugin is None:
3768            print("_set_midiCountInfo failed for", pluginId)
3769            return
3770        plugin.midiCountInfo = info
3771
3772    def _set_parameterCountInfo(self, pluginId, count, info):
3773        plugin = self.fPluginsInfo.get(pluginId, None)
3774        if plugin is None:
3775            print("_set_parameterCountInfo failed for", pluginId)
3776            return
3777
3778        plugin.parameterCount = count
3779        plugin.parameterCountInfo = info
3780
3781        # clear
3782        plugin.parameterInfo  = []
3783        plugin.parameterData  = []
3784        plugin.parameterRanges = []
3785        plugin.parameterValues = []
3786
3787        # add placeholders
3788        for _ in range(count):
3789            plugin.parameterInfo.append(PyCarlaParameterInfo.copy())
3790            plugin.parameterData.append(PyParameterData.copy())
3791            plugin.parameterRanges.append(PyParameterRanges.copy())
3792            plugin.parameterValues.append(0.0)
3793
3794    def _set_programCount(self, pluginId, count):
3795        plugin = self.fPluginsInfo.get(pluginId, None)
3796        if plugin is None:
3797            print("_set_internalValue failed for", pluginId)
3798            return
3799
3800        plugin.programCount = count
3801        plugin.programNames = ["" for _ in range(count)]
3802
3803    def _set_midiProgramCount(self, pluginId, count):
3804        plugin = self.fPluginsInfo.get(pluginId, None)
3805        if plugin is None:
3806            print("_set_internalValue failed for", pluginId)
3807            return
3808
3809        plugin.midiProgramCount = count
3810        plugin.midiProgramData = [PyMidiProgramData.copy() for _ in range(count)]
3811
3812    def _set_customDataCount(self, pluginId, count):
3813        plugin = self.fPluginsInfo.get(pluginId, None)
3814        if plugin is None:
3815            print("_set_internalValue failed for", pluginId)
3816            return
3817
3818        plugin.customDataCount = count
3819        plugin.customData = [PyCustomData.copy() for _ in range(count)]
3820
3821    def _set_parameterInfo(self, pluginId, paramIndex, info):
3822        plugin = self.fPluginsInfo.get(pluginId, None)
3823        if plugin is None:
3824            print("_set_parameterInfo failed for", pluginId)
3825            return
3826        if paramIndex < plugin.parameterCount:
3827            plugin.parameterInfo[paramIndex] = info
3828        else:
3829            print("_set_parameterInfo failed for", pluginId, "and index", paramIndex)
3830
3831    def _set_parameterData(self, pluginId, paramIndex, data):
3832        plugin = self.fPluginsInfo.get(pluginId, None)
3833        if plugin is None:
3834            print("_set_parameterData failed for", pluginId)
3835            return
3836        if paramIndex < plugin.parameterCount:
3837            plugin.parameterData[paramIndex] = data
3838        else:
3839            print("_set_parameterData failed for", pluginId, "and index", paramIndex)
3840
3841    def _set_parameterRanges(self, pluginId, paramIndex, ranges):
3842        plugin = self.fPluginsInfo.get(pluginId, None)
3843        if plugin is None:
3844            print("_set_parameterRanges failed for", pluginId)
3845            return
3846        if paramIndex < plugin.parameterCount:
3847            plugin.parameterRanges[paramIndex] = ranges
3848        else:
3849            print("_set_parameterRanges failed for", pluginId, "and index", paramIndex)
3850
3851    def _set_parameterRangesUpdate(self, pluginId, paramIndex, ranges):
3852        plugin = self.fPluginsInfo.get(pluginId, None)
3853        if plugin is None:
3854            print("_set_parameterRangesUpdate failed for", pluginId)
3855            return
3856        if paramIndex < plugin.parameterCount:
3857            plugin.parameterRanges[paramIndex].update(ranges)
3858        else:
3859            print("_set_parameterRangesUpdate failed for", pluginId, "and index", paramIndex)
3860
3861    def _set_parameterValue(self, pluginId, paramIndex, value):
3862        plugin = self.fPluginsInfo.get(pluginId, None)
3863        if plugin is None:
3864            print("_set_parameterValue failed for", pluginId)
3865            return
3866        if paramIndex < plugin.parameterCount:
3867            plugin.parameterValues[paramIndex] = value
3868        else:
3869            print("_set_parameterValue failed for", pluginId, "and index", paramIndex)
3870
3871    def _set_parameterDefault(self, pluginId, paramIndex, value):
3872        plugin = self.fPluginsInfo.get(pluginId, None)
3873        if plugin is None:
3874            print("_set_parameterDefault failed for", pluginId)
3875            return
3876        if paramIndex < plugin.parameterCount:
3877            plugin.parameterRanges[paramIndex]['def'] = value
3878        else:
3879            print("_set_parameterDefault failed for", pluginId, "and index", paramIndex)
3880
3881    def _set_parameterMappedControlIndex(self, pluginId, paramIndex, index):
3882        plugin = self.fPluginsInfo.get(pluginId, None)
3883        if plugin is None:
3884            print("_set_parameterMappedControlIndex failed for", pluginId)
3885            return
3886        if paramIndex < plugin.parameterCount:
3887            plugin.parameterData[paramIndex]['mappedControlIndex'] = index
3888        else:
3889            print("_set_parameterMappedControlIndex failed for", pluginId, "and index", paramIndex)
3890
3891    def _set_parameterMappedRange(self, pluginId, paramIndex, minimum, maximum):
3892        plugin = self.fPluginsInfo.get(pluginId, None)
3893        if plugin is None:
3894            print("_set_parameterMappedRange failed for", pluginId)
3895            return
3896        if paramIndex < plugin.parameterCount:
3897            plugin.parameterData[paramIndex]['mappedMinimum'] = minimum
3898            plugin.parameterData[paramIndex]['mappedMaximum'] = maximum
3899        else:
3900            print("_set_parameterMappedRange failed for", pluginId, "and index", paramIndex)
3901
3902    def _set_parameterMidiChannel(self, pluginId, paramIndex, channel):
3903        plugin = self.fPluginsInfo.get(pluginId, None)
3904        if plugin is None:
3905            print("_set_parameterMidiChannel failed for", pluginId)
3906            return
3907        if paramIndex < plugin.parameterCount:
3908            plugin.parameterData[paramIndex]['midiChannel'] = channel
3909        else:
3910            print("_set_parameterMidiChannel failed for", pluginId, "and index", paramIndex)
3911
3912    def _set_currentProgram(self, pluginId, pIndex):
3913        plugin = self.fPluginsInfo.get(pluginId, None)
3914        if plugin is None:
3915            print("_set_currentProgram failed for", pluginId)
3916            return
3917        plugin.programCurrent = pIndex
3918
3919    def _set_currentMidiProgram(self, pluginId, mpIndex):
3920        plugin = self.fPluginsInfo.get(pluginId, None)
3921        if plugin is None:
3922            print("_set_currentMidiProgram failed for", pluginId)
3923            return
3924        plugin.midiProgramCurrent = mpIndex
3925
3926    def _set_programName(self, pluginId, pIndex, name):
3927        plugin = self.fPluginsInfo.get(pluginId, None)
3928        if plugin is None:
3929            print("_set_programName failed for", pluginId)
3930            return
3931        if pIndex < plugin.programCount:
3932            plugin.programNames[pIndex] = name
3933        else:
3934            print("_set_programName failed for", pluginId, "and index", pIndex)
3935
3936    def _set_midiProgramData(self, pluginId, mpIndex, data):
3937        plugin = self.fPluginsInfo.get(pluginId, None)
3938        if plugin is None:
3939            print("_set_midiProgramData failed for", pluginId)
3940            return
3941        if mpIndex < plugin.midiProgramCount:
3942            plugin.midiProgramData[mpIndex] = data
3943        else:
3944            print("_set_midiProgramData failed for", pluginId, "and index", mpIndex)
3945
3946    def _set_customData(self, pluginId, cdIndex, data):
3947        plugin = self.fPluginsInfo.get(pluginId, None)
3948        if plugin is None:
3949            print("_set_customData failed for", pluginId)
3950            return
3951        if cdIndex < plugin.customDataCount:
3952            plugin.customData[cdIndex] = data
3953        else:
3954            print("_set_customData failed for", pluginId, "and index", cdIndex)
3955
3956    def _set_peaks(self, pluginId, in1, in2, out1, out2):
3957        pluginInfo = self.fPluginsInfo.get(pluginId, None)
3958        if pluginInfo is not None:
3959            pluginInfo.peaks = [in1, in2, out1, out2]
3960
3961    def _removePlugin(self, pluginId):
3962        pluginCountM1 = len(self.fPluginsInfo)-1
3963
3964        if pluginId >= pluginCountM1:
3965            self.fPluginsInfo[pluginId] = PluginStoreInfo()
3966            return
3967
3968        # push all plugins 1 slot back starting from the plugin that got removed
3969        for i in range(pluginId, pluginCountM1):
3970            self.fPluginsInfo[i] = self.fPluginsInfo[i+1]
3971
3972        self.fPluginsInfo[pluginCountM1] = PluginStoreInfo()
3973
3974    def _switchPlugins(self, pluginIdA, pluginIdB):
3975        tmp = self.fPluginsInfo[pluginIdA]
3976        self.fPluginsInfo[pluginIdA] = self.fPluginsInfo[pluginIdB]
3977        self.fPluginsInfo[pluginIdB] = tmp
3978
3979    def _setViaCallback(self, action, pluginId, value1, value2, value3, valuef, valueStr):
3980        if action == ENGINE_CALLBACK_ENGINE_STARTED:
3981            self.fBufferSize = value3
3982            self.fSampleRate = valuef
3983            if value1 == ENGINE_PROCESS_MODE_CONTINUOUS_RACK:
3984                maxPluginId = MAX_RACK_PLUGINS
3985            elif value1 == ENGINE_PROCESS_MODE_PATCHBAY:
3986                maxPluginId = MAX_PATCHBAY_PLUGINS
3987            else:
3988                maxPluginId = MAX_DEFAULT_PLUGINS
3989            self._reset(maxPluginId)
3990
3991        elif action == ENGINE_CALLBACK_BUFFER_SIZE_CHANGED:
3992            self.fBufferSize = value1
3993
3994        elif action == ENGINE_CALLBACK_SAMPLE_RATE_CHANGED:
3995            self.fSampleRate = valuef
3996
3997        elif action == ENGINE_CALLBACK_PLUGIN_REMOVED:
3998            self._removePlugin(pluginId)
3999
4000        elif action == ENGINE_CALLBACK_PLUGIN_RENAMED:
4001            self._set_pluginName(pluginId, valueStr)
4002
4003        elif action == ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED:
4004            if value1 < 0:
4005                self._set_internalValue(pluginId, value1, valuef)
4006            else:
4007                self._set_parameterValue(pluginId, value1, valuef)
4008
4009        elif action == ENGINE_CALLBACK_PARAMETER_DEFAULT_CHANGED:
4010            self._set_parameterDefault(pluginId, value1, valuef)
4011
4012        elif action == ENGINE_CALLBACK_PARAMETER_MAPPED_CONTROL_INDEX_CHANGED:
4013            self._set_parameterMappedControlIndex(pluginId, value1, value2)
4014
4015        elif action == ENGINE_CALLBACK_PARAMETER_MAPPED_RANGE_CHANGED:
4016            minimum, maximum = (float(i) for i in valueStr.split(":"))
4017            self._set_parameterMappedRange(pluginId, value1, minimum, maximum)
4018
4019        elif action == ENGINE_CALLBACK_PARAMETER_MIDI_CHANNEL_CHANGED:
4020            self._set_parameterMidiChannel(pluginId, value1, value2)
4021
4022        elif action == ENGINE_CALLBACK_PROGRAM_CHANGED:
4023            self._set_currentProgram(pluginId, value1)
4024
4025        elif action == ENGINE_CALLBACK_MIDI_PROGRAM_CHANGED:
4026            self._set_currentMidiProgram(pluginId, value1)
4027
4028# ---------------------------------------------------------------------------------------------------------------------
4029