Skip to content

Commit

Permalink
Better error Carla detection
Browse files Browse the repository at this point in the history
  • Loading branch information
00sapo committed Jul 23, 2021
1 parent fa1ed20 commit d34bbfa
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 30 deletions.
12 changes: 12 additions & 0 deletions pycarla/audiorecorder.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@ def __init__(self):
"""
super().__init__("AudioRecorder")

# a simple callback that ends the processing if
# carla disconnects
global recorder_unregister_callback

@self.client.set_client_registration_callback
def recorder_unregister_callback(name, register):
if 'carla' in name.lower() and not register:
# this check works for both `pycarla` and `Carla-something`
print("Carla disconnected: disconnecting " + self.client.name)
self.end_wait.set()
self.error = True

def activate(self):
"""
Activate the recording client and set the connections.
Expand Down
53 changes: 35 additions & 18 deletions pycarla/carla.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from typing import List
import argparse
import fnmatch
import os
Expand Down Expand Up @@ -56,13 +57,12 @@ def download():


def run_carla():
server = JackServer(['-R', '-d', 'alsa'])
carla = Carla("", server, min_wait=0, nogui=False)
carla = Carla("", ['-R', '-d', 'alsa'], min_wait=0, nogui=False)
carla.start()
carla.process.wait()
try:
carla.kill()
except:
except Exception:
print("Processes already closed!")


Expand All @@ -83,27 +83,33 @@ def run_carla():
class Carla(ExternalProcess):
def __init__(self,
proj_path: str,
server: JackServer,
server_options: List[str] = [],
min_wait: float = 0,
nogui: bool = True):
"""
Creates a Carla object, ready to be started.
`min_wait` is the minimum amount of seconds waited when starting Carla;
it is useful if your preset takes a bit to be loaded.
* `server_options` are the the options that will be used to start
`jackd`; the format is similar to `subprocess.Popen` -- e.g. ``['-d',
'alsa', '-r', '48000']
`nogui` is False if you want to use the gui
* `min_wait` is the minimum amount of seconds waited when starting
Carla; it is useful if your preset takes a bit to be loaded.
* `nogui` is False if you want to use the gui
"""
super().__init__()

self.proj_path = proj_path
self.server = server
self.server = JackServer(server_options)
self.min_wait = min_wait
if nogui:
self.nogui = "-n"
else:
self.nogui = ""

self.error = False

if sys.platform == 'linux':
if not os.path.exists(CARLA_PATH):
raise Warning("Carla seems not to be installed. Run \
Expand All @@ -114,15 +120,6 @@ def __init__(self,
"Carla seems not to be installed. Download it and put the \
``Carla`` command in your path.")

global carla_unregister_callback

# a simple callback that restart carla if
# carla disconnects
@self.server.client.set_client_registration_callback
def carla_unregister_callback(name, register):
if not self.exists():
self.restart_carla()

def restart_carla(self):
"""
Only restarts Carla, not the Jack server!
Expand All @@ -144,6 +141,9 @@ def __make_carla_popen(self, proj_path):
[CARLA_PATH + "Carla", self.nogui, proj_path],
preexec_fn=os.setsid)

def get_ports(self):
return [port.name for port in self.client.get_ports()]

def start(self):
"""
Start carla and Jack and wait `self.min_wait` seconds after a Carla
Expand Down Expand Up @@ -175,10 +175,27 @@ def start(self):
start = time.time()
time.sleep(0.1)

self.client = jack.Client("pycarla")

global carla_unregister_callback

# a simple callback that restart carla if
# carla disconnects
@self.client.set_process_callback
def carla_process(frames):
if (self.client.last_time_frames / frames) % 8 == 0:
if not self.exists():
print("Carla doesn't exists anymore, restarting it")
self.restart_carla()
self.error = True
self.client.activate()

def kill_carla(self):
"""
kill carla, but not the server
"""
self.client.deactivate()
self.client.close()
kill_psutil_process(self.process)

def kill(self):
Expand All @@ -204,7 +221,7 @@ def exists(self, ports=["Carla:events*", "Carla:audio*"]):
bool: True if all ports in `ports` exist and the Carla process is
running, false otherwise
"""
real_ports = self.server.get_ports()
real_ports = self.get_ports()
for port in ports:
if not fnmatch.filter(real_ports, port):
return False
Expand Down
12 changes: 0 additions & 12 deletions pycarla/jackserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ def start(self):
Starts the server if not already started
"""
try:
self.connect()
self.process = find_procs_by_name('jackd')[0]
except (IndexError, jack.JackOpenError) as e:
print("Jack server is not running, starting it!")
Expand All @@ -39,13 +38,6 @@ def start(self):
else:
raise e
time.sleep(1)
self.connect()

def connect(self):
if not hasattr(self, 'client'):
self.client = jack.Client('pycarla')
if not hasattr(self, 'client'):
print("Cannot connect to Jack server!")

def restart(self):
"""
Expand All @@ -55,10 +47,6 @@ def restart(self):
self.wait()
self.start()

def get_ports(self) -> List[str]:
return [port.name for port in self.client.get_ports()]

def kill(self):
self.client.close()
kill_psutil_process(self.process)
super().kill()
11 changes: 11 additions & 0 deletions pycarla/midiplayer.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,17 @@ def __init__(self):
For now, only one Carla instance should be active.
"""
super().__init__("MIDIPlayer")
# a simple callback that ends the processing if
# carla disconnects
global player_unregister_callback

@self.client.set_client_registration_callback
def player_unregister_callback(name, register):
if 'carla' in name.lower() and not register:
# this check works for both `pycarla` and `Carla-something`
print("Carla disconnected: disconnecting " + self.client.name)
self.end_wait.set()
self.error = True

def activate(self):
"""
Expand Down

0 comments on commit d34bbfa

Please sign in to comment.