Hello, I’m developing an app in Python with a Tkinter GUI that communicates with Audacity via piping. Just wanted to see if anyone could help me get a sense of what it means when both Audacity and the Python runner stop responding, and how to debug these issues. It does not seem to be tied to any particular command. Sometimes I can run hundreds of commands with no problem, and other times things will just stop responding out of nowhere. The app now has over a thousand LOC, but I will attach the part of the code that interacts with Audacity and hopefully folks can help me add some try/except statements or debugging statements to my code, with the goal of preventing the dreaded spinning wheel and “application not responding” message.
The code below shows the utils.py file which contains the code that actually interacts with Audacity, and then the processor.py file which contains a class that runs the do_command function many times in succession.
# utils.py
import os
from sys import exit
from tkinter import messagebox
TONAME = '/tmp/audacity_script_pipe.to.' + str(os.getuid())
FROMNAME = '/tmp/audacity_script_pipe.from.' + str(os.getuid())
try:
TOFILE = open(TONAME, 'w')
FROMFILE = open(FROMNAME, 'rt')
except FileNotFoundError:
messagebox.showerror("Pipe not found",
"""The audacity pipe file was not found.
Please make sure Audacity is open before launching the application.""")
exit()
def send_command(command):
TOFILE.write(command + "\n")
TOFILE.flush()
def get_response():
"""Return the command response."""
result = ''
line = ''
while True:
result += line
line = FROMFILE.readline()
if line == '\n' and len(result) > 0:
break
return result
def do_command(command):
"""Send one command, and return the response."""
send_command(command)
response = get_response()
return response
# processor.py
import json
import os
from utils import do_command
class Processor:
def __init__(self, master):
self.master = master
def process(self, params, processes):
self.counter_start = int(params["counter_start"])
self.num_iterations = int(params["num_iterations"])
if self.num_iterations < 1:
return
if params["import"] == True:
(do_command("ImportRaw:"))
# Get audio info
info = (do_command("GetInfo: Type=Tracks"))
# Trim info
info = info[1:-26]
# Load track data
track_data = json.loads(info)
first_track_end = track_data[0]["end"]
# Set start and end
start = 0.2
end = first_track_end
# Create file path if does not already exist
folder_name = params["folder_name"]
filepath = f"/Users/jholland/Pictures/glitch/{folder_name}"
if not os.path.exists(filepath):
os.mkdir(filepath)
for i in range(self.counter_start,
self.num_iterations + self.counter_start):
if params["fill_gaps"] == True:
if i not in params["gaps"]:
continue
# Copy audio
(do_command("SelectAll:"))
(do_command("Copy:"))
# Select portion to process
(do_command(f"SelectTime: Start={start} End={end}"))
for effect in processes:
command = effect["name"] + ": "
for param in effect["params"]:
start_val = float(param["start_val"])
end_val = float(param["end_val"])
value = self.get_value(start_val, end_val, i)
command += param["name"] + "=" + str(value) + " "
print(command)
(do_command(command))
# Select all for export
(do_command("SelectAll:"))
# Export
filename = f"{filepath}/{i}.raw"
command = f"Export2: Filename={filename}"
(do_command(command))
# Select all, delete, and paste original audio
(do_command("SelectAll:"))
(do_command("Delete:"))
(do_command("Paste:"))
def get_value(self, start_val, end_val, idx):
if idx == 0:
return start_val
if idx == self.num_iterations:
return end_val
inc = (end_val - start_val) / self.num_iterations
return start_val + (inc * (idx - self.counter_start))