simple-carla 1.5.1__tar.gz → 2.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: simple_carla
3
- Version: 1.5.1
3
+ Version: 2.1.0
4
4
  Summary: An easy-to-use, object-oriented interface to the carla plugin host.
5
5
  Author-email: Leon Dionne <ldionne@dridesign.sh.cn>
6
6
  Description-Content-Type: text/markdown
@@ -18,7 +18,7 @@ build-backend = "flit_core.buildapi"
18
18
  sc-plugin-def = "simple_carla.scripts.sc_plugin_def:main"
19
19
 
20
20
  [bumpver]
21
- current_version = "1.5.1"
21
+ current_version = "2.1.0"
22
22
  version_pattern = "MAJOR.MINOR.PATCH"
23
23
  commit_message = "Bump version {old_version} -> {new_version}"
24
24
  commit = true
@@ -22,7 +22,7 @@ An easy-to-use, object-oriented interface to the carla plugin host.
22
22
  """
23
23
  import os, sys, threading, time, logging, traceback
24
24
  from ctypes import byref, cast, c_char_p, c_void_p, POINTER
25
- from functools import wraps
25
+ from functools import wraps, cached_property
26
26
  from struct import pack
27
27
  from numpy import zeros as np_zeros
28
28
  from log_soso import StreamToLogger
@@ -234,7 +234,7 @@ from carla_backend import (
234
234
  )
235
235
 
236
236
 
237
- __version__ = "1.5.1"
237
+ __version__ = "2.1.0"
238
238
 
239
239
 
240
240
  # -------------------------------------------------------------------
@@ -1280,14 +1280,15 @@ class _SimpleCarla(CarlaHostDLL):
1280
1280
  the "_plugins" dict.
1281
1281
  """
1282
1282
  if plugin_id in self._plugins:
1283
- logging.warning('cb_plugin_added: Cannot add plugin %s', plugin_id)
1284
- logging.warning('"%s" - plugin %s already in _plugins"', carla_plugin_name, self._plugins[plugin_id])
1283
+ logging.error('cb_plugin_added: Cannot add plugin %s', plugin_id)
1284
+ logging.error('"%s" - plugin %s already in _plugins"', carla_plugin_name, self._plugins[plugin_id])
1285
1285
  return
1286
1286
  if carla_plugin_name in self._plugin_by_uuid:
1287
1287
  self._plugins[plugin_id] = self._plugin_by_uuid[carla_plugin_name]
1288
1288
  self._plugins[plugin_id].post_embed_init(plugin_id) # Set up parameters, etc.
1289
1289
  else:
1290
- logging.warning('cb_plugin_added: Plugin "%s" not found in _plugin_by_uuid when added', carla_plugin_name)
1290
+ logging.error('cb_plugin_added: Plugin "%s" not found in _plugin_by_uuid when added',
1291
+ carla_plugin_name)
1291
1292
 
1292
1293
  def cb_plugin_removed(self, plugin_id):
1293
1294
  if plugin_id in self._plugins:
@@ -1295,7 +1296,8 @@ class _SimpleCarla(CarlaHostDLL):
1295
1296
  if plugin.uuid in self._plugin_by_uuid:
1296
1297
  del self._plugin_by_uuid[plugin.uuid]
1297
1298
  else:
1298
- logging.warning('cb_plugin_removed: "%s" uuid %s not in self._plugin_by_uuid', plugin, plugin.uuid)
1299
+ logging.error('cb_plugin_removed: "%s" uuid %s not in self._plugin_by_uuid',
1300
+ plugin, plugin.uuid)
1299
1301
  self._alert_plugin_removed(plugin)
1300
1302
  # Renumber plugins per Carla plugin_id conventions:
1301
1303
  for i in range(plugin_id, len(self._plugins) - 1):
@@ -1306,7 +1308,7 @@ class _SimpleCarla(CarlaHostDLL):
1306
1308
  if self.is_clear():
1307
1309
  self._alert_last_plugin_removed()
1308
1310
  else:
1309
- logging.warning('cb_plugin_removed: Plugin removed (%d) not in _plugins', plugin_id)
1311
+ logging.error('cb_plugin_removed: Plugin removed (%d) not in _plugins', plugin_id)
1310
1312
 
1311
1313
  def cb_plugin_renamed(self, plugin_id, new_name):
1312
1314
  self._plugins[plugin_id].plugin_renamed(new_name)
@@ -1316,34 +1318,10 @@ class _SimpleCarla(CarlaHostDLL):
1316
1318
 
1317
1319
  def cb_parameter_value_changed(self, plugin_id, index, value):
1318
1320
  if plugin_id in self._plugins:
1319
- plugin = self._plugins[plugin_id]
1320
- if index == PARAMETER_NULL:
1321
- return
1322
- elif index == PARAMETER_ACTIVE:
1323
- plugin.active = value != 0
1324
- elif index == PARAMETER_DRYWET:
1325
- plugin.dry_wet = value
1326
- elif index == PARAMETER_VOLUME:
1327
- plugin.volume = value
1328
- elif index == PARAMETER_BALANCE_LEFT:
1329
- plugin.balance_left = value
1330
- elif index == PARAMETER_BALANCE_RIGHT:
1331
- plugin.balance_right = value
1332
- elif index == PARAMETER_PANNING:
1333
- plugin.panning = value
1334
- elif index == PARAMETER_CTRL_CHANNEL:
1335
- plugin.ctrl_channel = value
1336
- elif index == PARAMETER_MAX:
1337
- return
1338
- else:
1339
- if index in plugin.parameters:
1340
- parameter = plugin.parameters[index]
1341
- parameter.internal_value_changed(value)
1342
- plugin.parameter_internal_value_changed(parameter, value)
1343
- else:
1344
- logging.error('Parameter index not in plugin.parameters')
1321
+ self._plugins[plugin_id].internal_value_changed(index, value)
1345
1322
  else:
1346
- logging.debug('cb_parameter_value_changed: plugin_id %s not in self._plugins', plugin_id)
1323
+ logging.error('cb_parameter_value_changed: plugin_id %s not in self._plugins',
1324
+ plugin_id)
1347
1325
 
1348
1326
  def cb_parameter_default_changed(self, plugin_id, index, value):
1349
1327
  self._plugins[plugin_id].parameter_default_changed(index, value)
@@ -1412,7 +1390,7 @@ class _SimpleCarla(CarlaHostDLL):
1412
1390
  use "on_client_added".
1413
1391
  """
1414
1392
  if client_id in self._clients:
1415
- return logging.warning('cb_patchbay_client_added: "%s" already in _clients as "%s"',
1393
+ return logging.error('cb_patchbay_client_added: "%s" already in _clients as "%s"',
1416
1394
  self._clients[client_id], client_name)
1417
1395
  plugin_uuid = client_name.rsplit("/")[-1]
1418
1396
  if plugin_uuid in self._plugin_by_uuid:
@@ -1443,7 +1421,8 @@ class _SimpleCarla(CarlaHostDLL):
1443
1421
  del self._sys_clients[client.client_name]
1444
1422
  del self._clients[client_id]
1445
1423
  else:
1446
- logging.warning('cb_patchbay_client_removed: Client removed (%s) not in _clients', client_id)
1424
+ logging.error('cb_patchbay_client_removed: Client removed (%s) not in _clients',
1425
+ client_id)
1447
1426
 
1448
1427
  def cb_patchbay_client_renamed(self, client_id, new_client_name):
1449
1428
  logging.debug('cb_patchbay_client_renamed: "%s" new name: "%s"',
@@ -1465,14 +1444,14 @@ class _SimpleCarla(CarlaHostDLL):
1465
1444
  self._clients[client_id].port_added(port_id, port_flags, group_id, port_name)
1466
1445
  self._alert_port_added(self._clients[client_id].ports[port_id])
1467
1446
  else:
1468
- logging.warning('cb_patchbay_port_added: client %s not in _clients', client_id)
1447
+ logging.error('cb_patchbay_port_added: client %s not in _clients', client_id)
1469
1448
 
1470
1449
  def cb_patchbay_port_removed(self, client_id, port_id):
1471
1450
  if client_id in self._clients:
1472
1451
  self._alert_port_removed(self._clients[client_id].ports[port_id])
1473
1452
  self._clients[client_id].port_removed(port_id)
1474
1453
  else:
1475
- logging.warning('cb_patchbay_port_removed: client %s not in _clients', client_id)
1454
+ logging.error('cb_patchbay_port_removed: client %s not in _clients', client_id)
1476
1455
 
1477
1456
  def cb_patchbay_port_changed(self, client_id, port_id, port_flags, group_id, new_port_name):
1478
1457
  logging.debug('cb_patchbay_port_changed: client_id %s port_id %s group_id %s new_port_name %s',
@@ -1519,7 +1498,7 @@ class _SimpleCarla(CarlaHostDLL):
1519
1498
  self._alert_connection_removed(connection)
1520
1499
  del self._connections[connection_id]
1521
1500
  else:
1522
- logging.warning('cb_patchbay_connection_removed: Connection %s not in ._connections',
1501
+ logging.error('cb_patchbay_connection_removed: Connection %s not in ._connections',
1523
1502
  connection_id)
1524
1503
 
1525
1504
  # ================================================================================
@@ -1561,6 +1540,8 @@ class _SimpleCarla(CarlaHostDLL):
1561
1540
  """
1562
1541
  Returns Plugin.
1563
1542
  "plugin_id" is the integer plugin_id assigned by Carla.
1543
+
1544
+ Raises IndexError
1564
1545
  """
1565
1546
  if plugin_id in self._plugins:
1566
1547
  return self._plugins[plugin_id]
@@ -1577,12 +1558,19 @@ class _SimpleCarla(CarlaHostDLL):
1577
1558
  """
1578
1559
  Returns PatchbayClient, either a SystemPatchbayClient or Plugin.
1579
1560
  "client_id" is the integer client_id assigned by Carla.
1561
+
1562
+ Raises IndexError
1580
1563
  """
1581
1564
  if client_id in self._clients:
1582
1565
  return self._clients[client_id]
1583
1566
  raise IndexError()
1584
1567
 
1585
1568
  def named_client(self, client_name):
1569
+ """
1570
+ Returns the PatchbayClient (system or Plugin) with the given "client_name"
1571
+
1572
+ Raises IndexError
1573
+ """
1586
1574
  for client in self._clients.values():
1587
1575
  if client.client_name == client_name:
1588
1576
  return client
@@ -1599,10 +1587,12 @@ class _SimpleCarla(CarlaHostDLL):
1599
1587
  """
1600
1588
  Returns the PatchbayClient with the given client_name.
1601
1589
  "client_name" is the same value that JACK audio connection kit uses.
1590
+
1591
+ Raises IndexError
1602
1592
  """
1603
1593
  if client_name in self._sys_clients:
1604
1594
  return self._sys_clients[client_name]
1605
- return None
1595
+ raise IndexError
1606
1596
 
1607
1597
  def is_clear(self):
1608
1598
  """
@@ -1615,14 +1605,15 @@ class _SimpleCarla(CarlaHostDLL):
1615
1605
 
1616
1606
  def system_clients(self):
1617
1607
  """
1618
- Generator which yields SystemPatchbayClient
1608
+ Generator which yields SystemPatchbayClient - all system clients.
1619
1609
  """
1620
1610
  for client in self._sys_clients.values():
1621
1611
  return client
1622
1612
 
1623
1613
  def system_audio_in_clients(self):
1624
1614
  """
1625
- Generator which yields SystemPatchbayClient
1615
+ Generator which yields SystemPatchbayClient - system clients with at least one
1616
+ audio in port.
1626
1617
  """
1627
1618
  for client in self._sys_clients.values():
1628
1619
  if client.audio_in_count > 0:
@@ -1630,7 +1621,8 @@ class _SimpleCarla(CarlaHostDLL):
1630
1621
 
1631
1622
  def system_audio_out_clients(self):
1632
1623
  """
1633
- Generator which yields SystemPatchbayClient
1624
+ Generator which yields SystemPatchbayClient - system clients with at least one
1625
+ audio out port.
1634
1626
  """
1635
1627
  for client in self._sys_clients.values():
1636
1628
  if client.audio_out_count > 0:
@@ -1638,7 +1630,7 @@ class _SimpleCarla(CarlaHostDLL):
1638
1630
 
1639
1631
  def system_audio_in_ports(self):
1640
1632
  """
1641
- Generator which yields PatchbayPort
1633
+ Generator which yields PatchbayPort - all audio in ports of all system clients.
1642
1634
  """
1643
1635
  for client in self._sys_clients.values():
1644
1636
  for port in client.audio_ins():
@@ -1646,7 +1638,7 @@ class _SimpleCarla(CarlaHostDLL):
1646
1638
 
1647
1639
  def system_audio_out_ports(self):
1648
1640
  """
1649
- Generator which yields PatchbayPort
1641
+ Generator which yields PatchbayPort - all audio out ports of all system clients.
1650
1642
  """
1651
1643
  for client in self._sys_clients.values():
1652
1644
  for port in client.audio_outs():
@@ -1654,7 +1646,8 @@ class _SimpleCarla(CarlaHostDLL):
1654
1646
 
1655
1647
  def system_midi_in_clients(self):
1656
1648
  """
1657
- Generator which yields SystemPatchbayClient
1649
+ Generator which yields SystemPatchbayClient - system clients with at least one
1650
+ MIDI in port.
1658
1651
  """
1659
1652
  for client in self._sys_clients.values():
1660
1653
  if client.midi_in_count > 0:
@@ -1662,7 +1655,8 @@ class _SimpleCarla(CarlaHostDLL):
1662
1655
 
1663
1656
  def system_midi_out_clients(self):
1664
1657
  """
1665
- Generator which yields SystemPatchbayClient
1658
+ Generator which yields SystemPatchbayClient - system clients with at least one
1659
+ MIDI out port.
1666
1660
  """
1667
1661
  for client in self._sys_clients.values():
1668
1662
  if client.midi_out_count > 0:
@@ -1670,7 +1664,7 @@ class _SimpleCarla(CarlaHostDLL):
1670
1664
 
1671
1665
  def system_midi_in_ports(self):
1672
1666
  """
1673
- Generator which yields PatchbayPort
1667
+ Generator which yields PatchbayPort - all MIDI in ports of all system clients.
1674
1668
  """
1675
1669
  for client in self._sys_clients.values():
1676
1670
  for port in client.midi_ins():
@@ -1678,7 +1672,7 @@ class _SimpleCarla(CarlaHostDLL):
1678
1672
 
1679
1673
  def system_midi_out_ports(self):
1680
1674
  """
1681
- Generator which yields PatchbayPort
1675
+ Generator which yields PatchbayPort - all MIDI out ports of all system clients.
1682
1676
  """
1683
1677
  for client in self._sys_clients.values():
1684
1678
  for port in client.midi_outs():
@@ -1703,7 +1697,8 @@ class _SimpleCarla(CarlaHostDLL):
1703
1697
  port1 must be an PatchbayPort which is an output.
1704
1698
  port2 must be an PatchbayPort which is an intput.
1705
1699
  """
1706
- if not self.patchbay_connect(True, port1.client_id, port1.port_id, port2.client_id, port2.port_id):
1700
+ if not self.patchbay_connect(True, port1.client_id, port1.port_id,
1701
+ port2.client_id, port2.port_id):
1707
1702
  logging.error('Patchbay connect FAILED! %s -> %s', port1, port2)
1708
1703
 
1709
1704
  # -------------------------------------------------------------------
@@ -1711,11 +1706,17 @@ class _SimpleCarla(CarlaHostDLL):
1711
1706
 
1712
1707
  def autoload(self, plugin, filename, callback = None):
1713
1708
  """
1714
- liquidsfz does not have an input file parameter, but instead, requests the host to display an open file dialog from which the user may select an SFZ file to load. This function triggers the plugin's host gui display which will call __file_callback(). When there is a plugin to autoload on deck, __file_callback() will return the "autoload_filename" property of the plugin, instead of showing the file open dialog and returning the result.
1709
+ Tell Carla to load the given filename for the given plugin.
1715
1710
 
1711
+ Some plugins, (such as liquidsfz) do not have an input file parameter, but
1712
+ instead, requests the host to display an open file dialog from which the user
1713
+ may select an SFZ file to load. This function triggers the plugin's host gui
1714
+ display which will call Carla.file_callback(). When there is a plugin to autoload
1715
+ on deck, Carla.file_callback() will return the "autoload_filename" property of
1716
+ the plugin, instead of showing the file open dialog and returning the result.
1716
1717
  """
1717
1718
  if self._autoload_plugin is not None:
1718
- raise Exception("Cannot set autoload plugin as it is already used by " + self._autoload_plugin)
1719
+ raise Exception(f'Autoload already used by "{self._autoload_plugin}"')
1719
1720
  self._autoload_plugin = plugin
1720
1721
  self._autoload_filename = filename
1721
1722
  #logging.debug('Autoloading "%s"', filename)
@@ -1769,11 +1770,11 @@ class _SimpleCarla(CarlaHostDLL):
1769
1770
  filter = charPtrToString(filter)
1770
1771
  if action == FILE_CALLBACK_OPEN:
1771
1772
  if self._open_file_callback is None:
1772
- raise RuntimeError('Carla wants to open a file, but no callback function is defined')
1773
+ raise RuntimeError('No callback function defined')
1773
1774
  str_filename = self._open_file_callback(caption, filter)
1774
1775
  elif action == FILE_CALLBACK_SAVE:
1775
1776
  if self._save_file_callback is None:
1776
- raise RuntimeError('Carla wants to open a file, but no callback function is defined')
1777
+ raise RuntimeError('No callback function defined')
1777
1778
  str_filename = self._save_file_callback(caption, filter)
1778
1779
  else:
1779
1780
  return None
@@ -2357,21 +2358,13 @@ class PatchbayClient:
2357
2358
  # -------------------------------------------------------------------
2358
2359
  # Other port access funcs:
2359
2360
 
2360
- def midi_input_port(self):
2361
- """
2362
- Returns PatchbayPort;
2363
- the first midi input port owned by this client.
2364
- """
2365
- for port in self.ports.values():
2366
- if port.is_midi and port.is_input:
2367
- return port
2368
- return None
2369
-
2370
2361
  def named_port(self, port_name):
2371
2362
  """
2372
2363
  Returns PatchbayPort;
2373
2364
  the port owned by this client whose "port_name" matches exactly.
2374
2365
  Note that the name does NOT include the client_name portion.
2366
+
2367
+ Raises IndexError
2375
2368
  """
2376
2369
  for port in self.ports.values():
2377
2370
  if port.port_name == port_name:
@@ -2562,26 +2555,25 @@ class PatchbayPort:
2562
2555
  for conn in self._connections.values():
2563
2556
  conn.disconnect()
2564
2557
 
2558
+ @cached_property
2565
2559
  def client(self):
2566
2560
  """
2567
2561
  Returns PatchbayClient.
2568
2562
  (May return class extending PatchbayClient, i.e. SystemPatchbayClient / Plugin)
2569
2563
  """
2570
- # TODO: Make this a cached property
2571
2564
  return Carla.instance.client(self.client_id)
2572
2565
 
2573
2566
  def client_name(self):
2574
2567
  """
2575
2568
  Returns (str) the JACK client name of the PatchbayClient which "owns" this PatchbayPort.
2576
2569
  """
2577
- # TODO: Make this a property
2578
- return self.client().client_name
2570
+ return self.client.client_name
2579
2571
 
2580
2572
  def jack_name(self):
2581
2573
  """
2582
2574
  Returns (str) fully qualified name in the format that JACK uses.
2583
2575
  """
2584
- return "{0}:{1}".format(self.client().client_name, self.port_name)
2576
+ return "{0}:{1}".format(self.client.client_name, self.port_name)
2585
2577
 
2586
2578
  def connections(self):
2587
2579
  """
@@ -2627,25 +2619,13 @@ class PatchbayPort:
2627
2619
  Returns list of PatchbayClient
2628
2620
  (May return class extending PatchbayClient, i.e. SystemPatchbayClient / Plugin)
2629
2621
  """
2630
- return [ port.client() for port in self.connected_ports() ]
2631
-
2632
- def encode_saved_state(self):
2633
- """
2634
- Returns a dict which is encoded to JSON when saving a project.
2635
- """
2636
- client = self.client()
2637
- return {
2638
- "system" : isinstance(client, SystemPatchbayClient),
2639
- "moniker" : f"{client.moniker}:{self.port_name}",
2640
- "client" : client.client_name if isinstance(client, SystemPatchbayClient) else client.uuid,
2641
- "port" : self.port_name
2642
- }
2622
+ return [ port.client for port in self.connected_ports() ]
2643
2623
 
2644
2624
  def __str__(self):
2645
2625
  return '<{0} {1} "{2}:{3}">'.format(
2646
2626
  ("Audio" if self.is_audio else "MIDI" if self.is_midi else "CV"),
2647
2627
  ("input" if self.is_input else "output"),
2648
- self.client().moniker, self.port_name
2628
+ self.client.moniker, self.port_name
2649
2629
  )
2650
2630
 
2651
2631
 
@@ -2681,11 +2661,9 @@ class PatchbayConnection:
2681
2661
  return f'<PatchbayConnection {self.connection_id} {self.out_port} to {self.in_port}>'
2682
2662
 
2683
2663
 
2684
-
2685
2664
  # -------------------------------------------------------------------
2686
2665
  # Plugins:
2687
2666
 
2688
-
2689
2667
  class Plugin(PatchbayClient):
2690
2668
  """
2691
2669
  An abstraction of a carla plugin.
@@ -2724,6 +2702,8 @@ class Plugin(PatchbayClient):
2724
2702
  super().__init__()
2725
2703
  self.saved_state = saved_state
2726
2704
  self.original_plugin_name = self.plugin_def['name']
2705
+ self.client_id = None # Assigned by carla
2706
+ self.client_name = None # Assigned by carla
2727
2707
  self.plugin_id = None
2728
2708
  self.moniker = None
2729
2709
  self.ports_ready = False
@@ -2880,7 +2860,6 @@ class Plugin(PatchbayClient):
2880
2860
  Called after post_embed_init() and all ports ready.
2881
2861
  You can check the state of this plugin using the "Plugin.is_ready" property.
2882
2862
  """
2883
- logging.debug('%s ready', self)
2884
2863
  if self._cb_ready is not None:
2885
2864
  self._cb_ready()
2886
2865
 
@@ -3009,16 +2988,6 @@ class Plugin(PatchbayClient):
3009
2988
  return '<{0} "{1}" (uuid {2}, client_id {3})>'.format(
3010
2989
  type(self).__name__, self.moniker, self.uuid, self.client_id)
3011
2990
 
3012
- def idle_fast(self):
3013
- """
3014
- Function which is called at a regular interval by client applications
3015
- Although this function is not used anywhere in this package, it is included for
3016
- your convenience.
3017
- Use it like so:
3018
- for plugin in Carla.instance.plugins():
3019
- plugin.idle_fast()
3020
- """
3021
-
3022
2991
  # -------------------------------------------------------------------
3023
2992
  # Functions called from Carla engine callbacks:
3024
2993
 
@@ -3051,6 +3020,34 @@ class Plugin(PatchbayClient):
3051
3020
  if self._cb_removed is not None:
3052
3021
  self._cb_removed()
3053
3022
 
3023
+ def internal_value_changed(self, index, value):
3024
+ if index == PARAMETER_NULL:
3025
+ return
3026
+ elif index == PARAMETER_ACTIVE:
3027
+ self.active_changed(bool(value))
3028
+ elif index == PARAMETER_DRYWET:
3029
+ self.dry_wet_changed(value)
3030
+ elif index == PARAMETER_VOLUME:
3031
+ self.volume_changed(value)
3032
+ elif index == PARAMETER_BALANCE_LEFT:
3033
+ self.balance_left_changed(value)
3034
+ elif index == PARAMETER_BALANCE_RIGHT:
3035
+ self.balance_right_changed(value)
3036
+ elif index == PARAMETER_PANNING:
3037
+ self.panning_changed(value)
3038
+ elif index == PARAMETER_CTRL_CHANNEL:
3039
+ self.ctrl_channel_changed(value)
3040
+ elif index == PARAMETER_MAX:
3041
+ return
3042
+ else:
3043
+ if index in self.parameters:
3044
+ parameter = self.parameters[index]
3045
+ parameter.internal_value_changed(value)
3046
+ self.parameter_internal_value_changed(parameter, value)
3047
+ else:
3048
+ logging.error('Parameter "%d" not in "%s" parameters',
3049
+ index, self)
3050
+
3054
3051
  def parameter_internal_value_changed(self, parameter, value):
3055
3052
  """
3056
3053
  Called by the Carla host engine when the internal value of a parameter has changed.
@@ -3139,8 +3136,31 @@ class Plugin(PatchbayClient):
3139
3136
  pass
3140
3137
 
3141
3138
  # -------------------------------------------------------------------
3142
- # Propery access functions which may trigger GUI changes
3143
- # or require setting a parameter in the engine:
3139
+ # Property changes triggered by internal value changes from carla
3140
+
3141
+ def active_changed(self, value):
3142
+ self._active = value
3143
+
3144
+ def dry_wet_changed(self, value):
3145
+ self._dry_wet = value
3146
+
3147
+ def volume_changed(self, value):
3148
+ self._volume = value
3149
+
3150
+ def balance_left_changed(self, value):
3151
+ self._balance_left = value
3152
+
3153
+ def balance_right_changed(self, value):
3154
+ self._balance_right = value
3155
+
3156
+ def panning_changed(self, value):
3157
+ self._panning = value
3158
+
3159
+ def ctrl_channel_changed(self, value):
3160
+ self._ctrl_channel = value
3161
+
3162
+ # -------------------------------------------------------------------
3163
+ # Properties accessed only from outside, not by carla
3144
3164
 
3145
3165
  @property
3146
3166
  def active(self):
@@ -3154,6 +3174,9 @@ class Plugin(PatchbayClient):
3154
3174
  """
3155
3175
  Set the "active" state of this Plugin.
3156
3176
  """
3177
+ self.set_active(value)
3178
+
3179
+ def set_active(self, value):
3157
3180
  if self.is_ready:
3158
3181
  self._active = value
3159
3182
  Carla.instance.set_active(self.plugin_id, bool(value))
@@ -3172,6 +3195,9 @@ class Plugin(PatchbayClient):
3172
3195
  Sets the dry/wet mix.
3173
3196
  "value" must be a float value in the range 0.0 to 1.0.
3174
3197
  """
3198
+ self.set_dry_wet(value)
3199
+
3200
+ def set_dry_wet(self, value):
3175
3201
  if isinstance(value, float):
3176
3202
  if value < 0.0 or value > 1.0:
3177
3203
  raise ValueError()
@@ -3192,6 +3218,9 @@ class Plugin(PatchbayClient):
3192
3218
  Sets the volume.
3193
3219
  "value" must be a float value in the range 0.0 to 1.0.
3194
3220
  """
3221
+ self.set_volume(value)
3222
+
3223
+ def set_volume(self, value):
3195
3224
  if isinstance(value, float):
3196
3225
  if value < 0.0 or value > 1.0:
3197
3226
  raise ValueError()
@@ -3212,6 +3241,9 @@ class Plugin(PatchbayClient):
3212
3241
  Sets the balance of the left channel (if applicable).
3213
3242
  "value" must be a float value in the range 0.0 to 1.0.
3214
3243
  """
3244
+ self.set_balance_left(value)
3245
+
3246
+ def set_balance_left(self, value):
3215
3247
  if isinstance(value, float):
3216
3248
  if value < -1.0 or value > 1.0:
3217
3249
  raise ValueError()
@@ -3232,6 +3264,9 @@ class Plugin(PatchbayClient):
3232
3264
  Sets the balance of the right channel (if applicable).
3233
3265
  "value" must be a float value in the range 0.0 to 1.0.
3234
3266
  """
3267
+ self.set_balance_right(value)
3268
+
3269
+ def set_balance_right(self, value):
3235
3270
  if isinstance(value, float):
3236
3271
  if value < -1.0 or value > 1.0:
3237
3272
  raise ValueError()
@@ -3262,6 +3297,9 @@ class Plugin(PatchbayClient):
3262
3297
  Sets the pan value (if applicable).
3263
3298
  "value" must be a float value in the range 0.0 to 1.0.
3264
3299
  """
3300
+ self.set_panning(value)
3301
+
3302
+ def set_panning(self, value):
3265
3303
  if isinstance(value, float):
3266
3304
  if value < -1.0 or value > 1.0:
3267
3305
  raise ValueError()
@@ -3280,7 +3318,9 @@ class Plugin(PatchbayClient):
3280
3318
  """
3281
3319
  Not sure what this does.
3282
3320
  """
3283
- # logging.debug('set ctrl_channel %s', value)
3321
+ self.set_ctrl_channel(value)
3322
+
3323
+ def set_ctrl_channel(self, value):
3284
3324
  Carla.instance.set_ctrl_channel(self.plugin_id, value)
3285
3325
  self._ctrl_channel = value
3286
3326
 
@@ -3405,6 +3445,7 @@ class Parameter:
3405
3445
  self.__value = Carla.instance.get_current_parameter_value(self.plugin_id, self.parameter_id)
3406
3446
  return self.__value
3407
3447
 
3448
+ @cached_property
3408
3449
  def plugin(self):
3409
3450
  """
3410
3451
  Returns the Plugin which "owns" this Parameter.
@@ -314,7 +314,6 @@ class CarlaQt(_SimpleCarla, QObject):
314
314
  self.sig_last_plugin_removed.emit()
315
315
 
316
316
 
317
-
318
317
  class AbstractQtPlugin(Plugin):
319
318
  """
320
319
  This is an abstract class for use by classes which you wish to inherit from a
@@ -329,10 +328,17 @@ class AbstractQtPlugin(Plugin):
329
328
  class MyVisualPlugin(QFrame, AbstractQtPlugin):
330
329
 
331
330
  # You must define these signals!
332
- sig_ready = pyqtSignal(Plugin)
333
- sig_removed = pyqtSignal(Plugin)
334
- sig_connection_change = pyqtSignal(PatchbayPort, PatchbayPort, bool)
335
- sig_parameter_changed = pyqtSignal(Plugin, Parameter, float)
331
+ sig_ready = pyqtSignal(Plugin)
332
+ sig_removed = pyqtSignal(Plugin)
333
+ sig_connection_change = pyqtSignal(PatchbayPort, PatchbayPort, bool)
334
+ sig_parameter_changed = pyqtSignal(Plugin, Parameter, float)
335
+ sig_active_changed = pyqtSignal(Plugin, bool)
336
+ sig_dry_wet_changed = pyqtSignal(Plugin, float)
337
+ sig_volume_changed = pyqtSignal(Plugin, float)
338
+ sig_balance_left_changed = pyqtSignal(Plugin, float)
339
+ sig_balance_right_changed = pyqtSignal(Plugin, float)
340
+ sig_panning_changed = pyqtSignal(Plugin, float)
341
+ sig_ctrl_channel_changed = pyqtSignal(Plugin, float)
336
342
 
337
343
  plugin_def = {...}
338
344
 
@@ -364,6 +370,37 @@ class AbstractQtPlugin(Plugin):
364
370
  if not self.removing_from_carla:
365
371
  self.sig_connection_change.emit(connection.out_port, connection.in_port, state)
366
372
 
373
+ # -------------------------------------------------------------------
374
+ # Property changes triggered by internal value changes from carla
375
+
376
+ def active_changed(self, value):
377
+ self._active = value
378
+ self.sig_active_changed.emit(self, value)
379
+
380
+ def dry_wet_changed(self, value):
381
+ self._dry_wet = value
382
+ self.sig_dry_wet_changed.emit(self, value)
383
+
384
+ def volume_changed(self, value):
385
+ self._volume = value
386
+ self.sig_volume_changed.emit(self, value)
387
+
388
+ def balance_left_changed(self, value):
389
+ self._balance_left = value
390
+ self.sig_balance_left_changed.emit(self, value)
391
+
392
+ def balance_right_changed(self, value):
393
+ self._balance_right = value
394
+ self.sig_balance_right_changed.emit(self, value)
395
+
396
+ def panning_changed(self, value):
397
+ self._panning = value
398
+ self.sig_panning_changed.emit(self, value)
399
+
400
+ def ctrl_channel_changed(self, value):
401
+ self._ctrl_channel = value
402
+ self.sig_ctrl_channel_changed.emit(self, value)
403
+
367
404
  def parameter_internal_value_changed(self, parameter, value):
368
405
  """
369
406
  Called by the Carla host engine when the internal value of a parameter has changed.
@@ -375,7 +412,6 @@ class AbstractQtPlugin(Plugin):
375
412
  self.sig_parameter_changed.emit(self, parameter, value)
376
413
 
377
414
 
378
-
379
415
  class QtPlugin(AbstractQtPlugin, QObject):
380
416
  """
381
417
  A class which inherits from both Plugin and QObject. It can be used by plugins
@@ -389,15 +425,22 @@ class QtPlugin(AbstractQtPlugin, QObject):
389
425
 
390
426
  """
391
427
 
392
- sig_ready = pyqtSignal(Plugin)
393
- sig_removed = pyqtSignal(Plugin)
394
- sig_connection_change = pyqtSignal(PatchbayPort, PatchbayPort, bool)
395
- sig_parameter_changed = pyqtSignal(Plugin, Parameter, float)
428
+ sig_ready = pyqtSignal(Plugin)
429
+ sig_removed = pyqtSignal(Plugin)
430
+ sig_connection_change = pyqtSignal(PatchbayPort, PatchbayPort, bool)
431
+ sig_parameter_changed = pyqtSignal(Plugin, Parameter, float)
432
+ sig_active_changed = pyqtSignal(Plugin, bool)
433
+ sig_dry_wet_changed = pyqtSignal(Plugin, float)
434
+ sig_volume_changed = pyqtSignal(Plugin, float)
435
+ sig_balance_left_changed = pyqtSignal(Plugin, float)
436
+ sig_balance_right_changed = pyqtSignal(Plugin, float)
437
+ sig_panning_changed = pyqtSignal(Plugin, float)
438
+ sig_ctrl_channel_changed = pyqtSignal(Plugin, float)
439
+
396
440
 
397
441
  def __init__(self, plugin_def=None, saved_state=None):
398
442
  QObject.__init__(self)
399
443
  Plugin.__init__(self, plugin_def, saved_state)
400
444
 
401
445
 
402
-
403
446
  # end simple_carla/qt.py
File without changes
File without changes
File without changes