EnvelopSound / EnvelopForLive

Free, open-source tools for Ambisonic 3D panning within Max for Live 10+
http://www.envelop.us/
GNU General Public License v2.0
483 stars 60 forks source link

Shifted audio channels when the routing is set to Chain #103

Open evgazloy opened 1 year ago

evgazloy commented 1 year ago

Not sure if this is a bug or not. When the routing of a device, for example, Stereo Panner is set to the master mode everything is ok and sounds as it's supposed to.

ok

And on E4L Master Bus I get these levels on the meter:

ok_meter

All 16 channels are used. Pay attention on the "pattern" of the levels.

But when the routing is set to the chain mode, only 14 channels are used and it sounds not as expected.

bad

As you can see it looks like it starts from the 3rd channel and the first two channels are lost.

For fixing that I added +1 block in e4l.bus.send.maxpat:

fix

Laptop: Apple M1 Pro OS: Mac OS Sonoma 14.0 (23A344) Live: 11.3.13 Max: 8.5.5

mcslee commented 1 year ago

Hrm, this is strange, I am not able to reproduce this on my system at the moment. How have you installed E4L? Did you checkout the GitHub repo directly or download a release ZIP file? Have you made any local modifications?

Can you share screenshots of the full Ableton mixer? Or share the whole live set project file in which this is occuring?

mcslee commented 1 year ago

Are there other devices on the chain in the track with the E4L Stereo Panner? I'm wondering if there are some other devices that may also have auxiliary inputs, e.g. assuming your track is called "Source Panner" can you show me what's in the dropdown if you try to route audio to this track from another?

Screen Shot 2023-11-11 at 7 44 34 PM
evgazloy commented 1 year ago

I've found what is causing this issue - any 3rd party plugin with a sidechain input, such as a compressor, placed before Panner.

evgazloy commented 1 year ago

You are right:

sends
mcslee commented 1 year ago

Okay - glad we've nailed down the source. The Live APIs for routing audio across tracks/devices are not based upon device objects, but rather they basically mimic what those routing UIs looks like. A routing target is specified via two parameters, each a list of options. (1) the "Track/Bus" options, (2) and then for each "Track/Bus" we get a secondary list of device inputs. The API provides the text labels of these destinations, but those are unreliable because the user may rename devices in Live - the text labels are the user-editable labels, not the canonical device name.

There is not a public API that I have found for "tell me which are the inputs of this particular device" - so I implemented that myself by iterating over the devices on the track, keeping a count of them and how many inputs they expose, and using this to determine where the routing inputs are for the next device in the chain.

This logic is all inside that e4l.bus.chain_index patch that you put the + 1 after. I just dug into that again, and into the further helper e4l.live.count_aux_inputs and lo and behold, it looks like I had left a comment about this very issue. This unfortunately suggests I have already gone to battle with it and could not find a general solution. If the Max 4 Live API doesn't tell us about VST sidechains, this may be very difficult to fix.

Screen Shot 2023-11-13 at 10 00 42 AM

This is admittedly one of the uglier parts of the E4L implementation, all hacking around the fact that Ableton is really fundamentally dealing with stereo audio pairs.

An ugly workaround is to break your track chain in two. You can put your VST chain on one Ableton track, then route the output of that track to a second track which Monitors its input with the E4L devices there. This way the VST sidechain inputs won't interfere with E4L's routing code. It's not ideal, but it works.

It seems like you're comfortable enough with Max to have dug into the patch and figured out what's roughly going on... totally open to suggestions or ideas if you're able to figure out how to get any info out of the Live API that would make it clear when there are extra VST sidechain inputs present. I'll also try to take a look to see if anything has changed in what the Live API reports since I originally wrote this.

mcslee commented 1 year ago

Just documenting a bit of what I've found as I refresh myself on this. Looking at the LOM documentation: https://docs.cycling74.com/max8/vignettes/live_object_model

What I'm seeing here is that the PluginDevice object type (what you get when you query a VST) does not have the audio_inputs field that can be seen on the MaxDevice object type immediately below. Don't think we can get at that programatically. Would probably require looking at all the available inputs for the track and matching by VST name.

Screen Shot 2023-11-13 at 11 52 40 AM
evgazloy commented 1 year ago

Yeah, I've seen that too. The basic workaround that came in my head was counting available routing channels. At first glance, it works even with multiple plugins with sidechain inputs.


----------begin_max5_patcher----------
1942.3oc6assjZiCD8YluBUjceJDJqK9Vp8SXqZeX28oMonDXAiRL1trMSlI
ox+9paPXlQ.h3FXeXeYlR1FZcT28oOpk4a2MZ775GEciQuG8OnQi91ciFYtj
9BibiGMdM+wEk7NyiMtR7k54eZ7D6s5EO1at76P3sWSVXth5odGkt8hUaVKq
JE8luDxOtX8l9sWE6tZCuew8xpUyZEK5sSs3nroj3IHBMeZj5e4S0CHSiPez
8greO8O0HrehwxJ0m8i5a986tS+mICCfq38BDFE4CkDXPIMgpQWLK07OhApG
Ejfhv25EbjXf.mBOJmVb5MyCJWh9EIF8anHT+8hJ0+DkcB807AalWXi+IgMi
wzvFSStxN02gx7gNJnNUFN4V4T6QknReHDeF9OxgQHNNUCJZNMTDNdBvtvuV
NsTT4Ai3zyvKRNoWjlYXbnoADhBMFaZEMhpBTmn2CPii.MYLQUMQAwzKFA6Z
QWGek3UnL2C1XQ.kJhMfJgFbpH34gy8UaLEl7PRtg.MNgcN4gy4Uq.ElEhkh
1x5u3yQl.SPJwDVhcZAtX0KreM9vQ7YfinShCqeiFs8u6vwh50qEU1k0cSip
BgYRigykIXkSKjK5mVJ67gWRFL9ML1DTxHwl7vzKkia651Kw4e9EoZNgVWWH
5lfDRkFmVzZ87DUwWKP0sHdExtB69rkxJwh5MVm.wSn.ClPAblw8yhMqPXqx
VJUu1.H6JwWvLPRyYYFY.jnKL65ActJ+jp7nrpYSOR1s08xQExtlR9Sy9Ycw
zbXbwLa.OK0r.giiFjK9vJgV2euupLwvnDxUkIIwDgxn2.kPl8YR7taZBP58
1xTkDa2t4M.ksJSHddj59BagAmtjVrMlLM5Fpqck2RsTnz0ZIj1Bz3q7dLsN
ScgGeXDXmocizo3KoyzLM8k.5uZRzYWMgFuGYoGsQGXaydTN8GM8x5JdIxLc
PKUk.ztCk8T6kpTYQ0cek5JxEYian23kzJBT4UoQwV4w3qbPtVBoOppryH7l
cR3kjZk8GcZAF5Ij1029jIPext.d2Gni+fnXlZNprwLdeeqbtJMsygbGzGMV
rdtnXunX8rqUIlnWzNSTwmWJNvMWyaZ1caycMKzfxo7FeZ5vIfVFLIxrjmgu
AkGTBZZEq7gwXXwnsoNraQIvC0gNLEnNzYgXL410gNy1K2T0vW74mIH+89fM
r7gtFhfioWY9PohCvC7.dyzV83jzqL3T4kckxEBuxvgUENMwHBHN8+PolLXx
LcxROmMMOA5VtpDdi3Ovkk5RUybRils3ddUknrymdkbX5XvV2qsWy377qbHb
OZt+CFIATZWRZzOzvdb3YZF6jqjrrbPkkQs0O+eYYGkXLGThQ2Y8eYIFGFsw
oZtFlAJWB1t4.rsiM58Pdk3RJq4E1r2WCQLnsvv1n3jPYSfDjcMspcYubO29
u14q.AE1d13dw.HWa8alojnk2txaUPPU.fwlMWkdK5zXo7AwTKcqGbl.ZBJA
aCeYA4KOuBByZDscxtdQ0hKD2t4Hb8pY3bNQP5oowrQCgtYzgIa3PGnh8jTV
V2tl2i9fBrH1GF6K.IBni.SQZuieCaahEI5m73QNDn96dYor+ITesoeb82K1
0LvZEwF52U4BH9lBYMpP7ftL9CRNxwDfzTAS848yf7.gstcJ6xrBnOrWSFuC
29fytb9k0U8cxuZB1v5bV.O1a6wfE8ZU+Zitjaygw.1aZLP8ldaeViCs0z96
K8ew+rnSExocFHK4FpqQrPtTJJP7NaNG9CiQ7pBjhza0JE+lIjsVwzw81258
WuLV0n.6Eu9pFLou9yWD6p2ztX6b1oVEg2M2KDcp3EqY+wyn2rD5PQngZnL6
2wQMjtYXC1PogfHL.FJI.DkCfczu2WmzPrHHrj56fbBCk7rk20xhlZkfwts7
6VlcmbNqTGyH.lYmbIHAnkfSE8n2PyfMDKjvGVLDVhDfknzm8P0sEh1cBrtr
lVef968PuHjhk6ZZuMxhjuazqmr3gMYCIOi5BPFlkBghJ+XIZTlUpcdlszj6
0IOavIZrPnoY.rFPCgmFDVMZZn90AaoPnovYGKbmFQMGUUlIp28Ji8hQI46k
JXFMz4MMjUHBDqPAQH.QNFEGhu.BHET4YHLTHNIHRXH4grzAgzFRVn0GFZ3.
IDRfLHfTH7ZziVxCaacRL0QtaXDLiF5bKDMGDPbrIgni5nk3vtViXKwgSh1U
vanysPXoiAIQhEJa2fsTHjCDHXgHjPqUfgVMYPlFezMnn+EnoSlrmnNN2zCN
yHnUSRBo9CADFGbH4ZoPXoPJ0kbTpMqnkT6FDyrMYY+AjmoymDEM7z8P3iwG
USV99+rEcaHwLBfo1ISk.vugCoKOPDffCpdNDTq3PpmS.YwKjhlXHHwwmy1G
FlkXgmHOLCQCgaJ9n5.n1WwK661E1d3ROeThsCsttOkPGNoANj5oXPBjCgD.
jnqfJHAgghBsL8fsTH6750Px1zbdSyC5CSz9zFaLdM+S0lZ+YSLCkU1gwlgs
hGjaed6U3sKtW1KVzuo0LuF+Xh8kcXr92APa0FoSHgBcJSZN+B8qDYWi6rOL
Gywce+t+EGwVL8B
-----------end_max5_patcher-----------
evgazloy commented 1 year ago

Needs further improvements, it's not working if a vst is placed after Panner.

evgazloy commented 1 year ago

Okay, I ended up matching device names as you suggested. Since we are dealing with names, we don't need to count the audio inputs of max devices anymore.


----------begin_max5_patcher----------
1768.3ocyassaaiCD8YmuBB+rWCMTT2JJ5K666OvhBCZYlD0paPhNaRK5+9J
RJ6jlRGMtdhUeHNwRx9nCmYNyEp78aVrbayip9krOv9W1hEe+lEKrGxbfEiu
ewxJ4i4kxd6ksrV8eMa+xxUtSoUOpsGtqYuV0NbQrfCmqXm8LCW8ewgCGrde
UQcoRa+x3OevgO9qOZqTmeeQ8ca5T4Z2sHDksNXESjjZ9UBXdkyWGv973mw8
0nepU49.KWtZ3G1mMm8G2bi4kUWFQuSpUdXX7YPP3MHXP5ZdzJVDDa3VHGAC
ojcexq4CDzvNQl07kHrjimsNZJxUTqIkex778U9XH2KCC+cYny7IDSa9nlgZ
F3geQdoGbtzKB.iMKN8Xj20ldeqbcm5NOLLQPiDiPDXXUbfkbgoyfDilskU5
ihgmgU7snXpkhQi5mHBC2JquibZ11oZU06Xc9zSS3z3wJxBrdrNyYbxUVO0X
JGLldUUSfyfhBD4LRshNQA3smGsqqnORsPq57w5.hLriNwtvUdzU1vdRcn3L
hzgF4WP77oC0z+T01FeRQwITEd5JnyUnSz0N7bvDpdr0C+DmiTazzxOBq+YL
1BVe4OWixeDDU9C.AqSL7MQLe0+XzaAuJtBpTbGoovQvyQw8fR6p2kRitanM
LutyADIJMFtl3zlli9uNQZkvXZDj.NXSlN1h4UOuxthb8580sx7ux1Uz2VJe
ZSsrR8AebNjHNen.hHqYEb+5JRZknbsk3kE8ZeDEHhnf0iU.17LwyPMC8kE4
JucnwSoIDMIxUufKgZzLDgZrj9HXxYPv2P7MVXTaCiBvJ8ZteJZpkcO8p7pi
efd4CpcaFtEGfXiTq6J1tW6FJ1hiLewRU0VkkMAqFORqraHxbPOZipVtsTch
SVIaaOdZ6Ysqym6pckpuWdm5WGHkRyjOHKJMXrwLGNy5U98x5ZUYuOCAQypZ
zP.VgRHQLCsV4qzTtfltjczimlLqMI+1ZFgznYvSsrKJ98WyfNuXNMdwNtCo
h+v7hCHxKFboz4ypWbYwCp0NEVeCeMiRSI2MVxXbiN+7xAroU00OTihpN29c
.+9x4SEuy8sPQTMBiNEvUHd2dW5y+1KSBN6bPVlj3lQRvgWwXwyappT0tE8i
2e06TOdztRWssuv8mYD5LEz6azXz1jVfqZ9vnYZD1d6.OgnQXKrw5gIgVaNB
U6C5ZT20sY+.Yf2zyBhJzZjr7PW7p3OkQcFR6TEFMlhf2S+U2WkOAoryvyLX
5YCk.AmPT5Zo7nYkdKs.hIMFj6FFDlZKHWloWcpQ8AQmwDMCmVnwMouwMt97
1aEhiEGbeF5szW9CHjps.0w4wwjjMK4OJM6ZlWYUfno3FlY4WD5cM68e9slg
a5uxu.RMsb21gJlCSquBh1odXnlWes4kQJugX2vJDIykOsGJlRpbLvEylb7Q
SqydtQ2Iy+puBiHZyCcLNK10MS16UcQGRX+KaEwN1+v9niqrhcexWIRzTTgP
35l01siS1haKofvNx.Z5HaTUEntkLNgFt+dHEpo8dl99ACmAgg+RpGdoneTK
h0eey9xcrdsrSyxuWVTOvS1scMUq887UkRig1M6BWIvgtMM921PeJ1ahR2tu
eskTabKvdXzwpDusoV2W7M2.OLhKzQTmWB3YehMfdq7ESYYj71KXYYQ8qepU
sXXN9Ouhz2ruK+fq1XBE1yvrS0qKpkl8G3EWiIaK6TK5XAJEAPYDfi4AeaRf
LOOCWNRgHP5vsykiDLERbJPhe0V8FDXYbLqd.EHM0pWbFUbZxnINUHEhAI9k
hT.FubR7HP.TbBA.EiQzKgBQuXLbRPBRH.JjBqTDVW7KMr0LazICaE+LuqJ1
01LzH5XxPwgQn4JfHyy63b2zgiRO9NJtuuJ1bAFiNDSARgHDqin.HL4e3TnU
Kvj+IlJflzefSERgXPhSARSEaFRxpGlzOVA8KVuAAPoDvnPLQswDPnPT0mBT
PITt3jfDppQH.Hyye1zd3TPINl7bbJ773X773jr5IvvoDBbx4XBa4TnDwwzD
Fmh183XRBBTjDjCH0htXfvD2x4TgDfYw6hc8vXknHtEvzuBmhh6ALSogSQsq
PLF80.BLS.ppjIY0CSuQhDpPB0p2Eij.a0qOe6zzsS0c5cumTnekB1QnCtLn
wT5DPQCO.JUDJxp.n5N3s6md7+6N29Xbnm4vf0jbuMoWFUKB.Fw.3jKBtmCf
PX7ItO836tz6ML4HETzY.pwT9q0151rAYa6ClG6S2UawXYk7KM1vtzU12VT6
dq8eEvkcpGJNb8tiH6xuuPqx066r2WKeL1sInKqZFBfq2WLJeLvtAHsahi4o
DrucbOPr60yM+3l+Gf9JXJC
-----------end_max5_patcher-----------
evgazloy commented 1 year ago

Committed to the fork https://github.com/evgazloy/EnvelopForLive

mcslee commented 1 year ago

Hrm, I've grabbed your code here, but it doesn't seem to be working for me. I'm seeing a channel offset problem just routing one panner into a meter. Note that there's no signal in the first channel (the W level).

Screen Shot 2023-11-14 at 3 20 01 PM

I think there are other pitfalls that this approach amy run into, since there is also no enforcement that device names are unique. For instance, two E4L Meter instances can be placed into the same chain (that's contrived, but you could imagine putting a Reverb between them, or some other device).

Screen Shot 2023-11-14 at 3 16 34 PM Screen Shot 2023-11-14 at 3 16 23 PM

It might be possible to implement some kind of hybrid counting-approach, knowing that E4L devices have pairs from 3/4 up to 17/18. But this starts to feel very hacky/brittle to me. I really wish the Live API exposed inputs on PluginDevice objects, or offered some kind of real connection between routing_channels and devices beyond "the string in this dictionary is the same as the device name." Not holding my breath for this though.

There are also potentially weird cases when you start putting devices in racks... which can have multiple chains both with devices of the same name.

Screen Shot 2023-11-14 at 3 29 19 PM