Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Splits zynmixer in half with input channels and mixbuses seperated to reduce latency.
Adds arbitrary quantity of effects send/returns.
Adds mixer processor to each audio chain which may be moved up/down the chain.
All mixer controls appear in control view allowing simple and consistent MIDI learn.
Removed MIDI learn from mixer view.
Effects return chains are MIDI + Audio.
  • Loading branch information
riban committed Nov 13, 2024
1 parent c26cff2 commit d31f2a9
Show file tree
Hide file tree
Showing 28 changed files with 1,050 additions and 1,480 deletions.
49 changes: 22 additions & 27 deletions zynautoconnect/zynthian_autoconnect.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,6 @@ def unset_alias(self, alias):
# Define some Constants and Global Variables
# -------------------------------------------------------------------------------

MAIN_MIX_CHAN = 17 # TODO: Get this from mixer

jclient = None # JACK client
thread = None # Thread to check for changed MIDI ports
lock = None # Manage concurrence
Expand Down Expand Up @@ -811,30 +809,23 @@ def audio_autoconnect():
# Chain audio routing
for chain_id in chain_manager.chains:
routes = chain_manager.get_chain_audio_routing(chain_id)
normalise = 0 in chain_manager.chains[chain_id].audio_out and chain_manager.chains[0].fader_pos == 0 and len(
chain_manager.chains[chain_id].audio_slots) == chain_manager.chains[chain_id].fader_pos
state_manager.zynmixer.normalise(
chain_manager.chains[chain_id].mixer_chan, normalise)
for dst in list(routes):
if isinstance(dst, int):
# Destination is a chain
route = routes.pop(dst)
dst_chain = chain_manager.get_chain(dst)
if dst_chain:
if dst_chain.audio_slots and dst_chain.fader_pos:
for proc in dst_chain.audio_slots[0]:
routes[proc.get_jackname()] = route
elif dst_chain.is_synth():
if dst_chain.is_synth():
proc = dst_chain.synth_slots[0][0]
if proc.type == "Special":
routes[proc.get_jackname()] = route
else:
if dst == 0:
for name in list(route):
if name.startswith('zynmixer:output'):
# Use mixer internal normalisation
route.remove(name)
routes[f"zynmixer:input_{dst_chain.mixer_chan + 1:02d}"] = route
for proc in chain_manager.chains[dst].audio_slots[0]:
#TODO: Handle internal normalisation
jackname = proc.get_jackname()
if jackname.startswith("zynmixer"):
jackname += f":input_{proc.mixer_chan:02d}"
routes[jackname] = route
for dst in routes:
if dst in sidechain_ports:
# This is an exact match so we do want to route exactly this
Expand All @@ -861,16 +852,20 @@ def audio_autoconnect():
dst = dst_ports[min(i, dst_count - 1)]
required_routes[dst.name].add(src.name)

# Connect metronome to aux
required_routes[f"zynmixer:input_{MAIN_MIX_CHAN}a"].add("zynseq:metronome")
required_routes[f"zynmixer:input_{MAIN_MIX_CHAN}b"].add("zynseq:metronome")

# Connect global audio player to aux
if state_manager.audio_player and state_manager.audio_player.jackname:
ports = jclient.get_ports(
state_manager.audio_player.jackname, is_output=True, is_audio=True)
required_routes[f"zynmixer:input_{MAIN_MIX_CHAN}a"].add(ports[0].name)
required_routes[f"zynmixer:input_{MAIN_MIX_CHAN}b"].add(ports[1].name)
try:
# Connect metronome to aux
required_routes[f"zynmixer_buses:input_00a"].add("zynseq:metronome")
required_routes[f"zynmixer_buses:input_00b"].add("zynseq:metronome")

# Connect global audio player to aux
if state_manager.audio_player and state_manager.audio_player.jackname:
ports = jclient.get_ports(
state_manager.audio_player.jackname, is_output=True, is_audio=True)
required_routes[f"zynmixer_buses:input_00a"].add(ports[0].name)
required_routes[f"zynmixer_buses:input_00b"].add(ports[1].name)
except Exception as e:
logging.warning(e)

# Connect inputs to aubionotes
if zynthian_gui_config.midi_aubionotes_enabled:
Expand Down Expand Up @@ -936,9 +931,9 @@ def audio_connect_ffmpeg(timeout=2.0):
try:
# TODO: Do we want post fader, post effects feed?
jclient.connect(
f"zynmixer:output_{MAIN_MIX_CHAN}a", "ffmpeg:input_1")
f"zynmixer_buses:input_00a", "ffmpeg:input_1")
jclient.connect(
f"zynmixer:output_{MAIN_MIX_CHAN}b", "ffmpeg:input_2")
f"zynmixer_buses:input_00b", "ffmpeg:input_2")
return
except:
sleep(0.1)
Expand Down
2 changes: 2 additions & 0 deletions zyngine/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"zynthian_controller",
"zynthian_lv2",
"zynthian_engine",
"zynthian_engine_audio_mixer",
"zynthian_engine_zynaddsubfx",
"zynthian_engine_linuxsampler",
"zynthian_engine_fluidsynth",
Expand All @@ -25,6 +26,7 @@
from zyngine.zynthian_controller import *
from zyngine.zynthian_lv2 import *
from zyngine.zynthian_engine import *
from zyngine.zynthian_engine_audio_mixer import *
from zyngine.zynthian_engine_zynaddsubfx import *
from zyngine.zynthian_engine_linuxsampler import *
from zyngine.zynthian_engine_fluidsynth import *
Expand Down
8 changes: 4 additions & 4 deletions zyngine/zynthian_audio_recorder.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,14 @@ def start_recording(self, processor=None):
if self.armed:
for port in sorted(self.armed):
cmd.append("--port")
cmd.append(f"zynmixer:output_{port + 1:02d}a")
cmd.append(f"zynmixer_chans:output_{port + 1:02d}a")
cmd.append("--port")
cmd.append(f"zynmixer:output_{port + 1:02d}b")
cmd.append(f"zynmixer_chans:output_{port + 1:02d}b")
else:
cmd.append("--port")
cmd.append("zynmixer:output_17a")
cmd.append("zynmixer_buses:output_0a")
cmd.append("--port")
cmd.append("zynmixer:output_17b")
cmd.append("zynmixer_buses:output_0b")

self.filename = self.get_new_filename()
cmd.append(self.filename)
Expand Down
Loading

0 comments on commit d31f2a9

Please sign in to comment.