markusschloesser / MackieC4_P3

A Mackie C4 Midi Remote Script for Ableton 11
16 stars 2 forks source link

this makes it non dynamic #72

Closed markusschloesser closed 1 year ago

markusschloesser commented 3 years ago

https://github.com/markusschloesser/MackieC4_P3/blob/ecfbb74cdd72faebc985b7b4bded1f0b7c095035/wip/MackieC4/Encoders.py#L72 tried that out yesterday, with this, it is only sent ones, but somehow the back channel is disrupted, meaning that turning vpots doesn't do anything anymore. Or does is work for you? So while liveobj_valid is a very good thing, it's not the solution for everything

BilldarBagdar commented 3 years ago

Two things. I haven't really looked at devices yet, and don't let the first problem like that deter you from continuing the testing. I mean, if I had stopped after the "ugly LCD text" instead of deleting another track, I never would have seen it work correctly thereafter.

What actions lead to this problem?
Do "all paths" lead to failed "twist actions"?

I probably won't have a lot of time today, but i will look into it. liveobj_valid() really is "all that" IMHO. It's just that it is revealing "other problems" now that were masked by different errors before (think Boost).

BilldarBagdar commented 3 years ago

Investigation Notes:

Are you also seeing this same behavior? What else?
(Don't go too far down the rabbit hole of writing down in detail what happens more than a few "bugs" beyond session startup. It's certainly ok to fix stuff as you encounter it if you want. I just mean since the "garbage in means garbage out" principle applies, don't burn a lot of cycles describing how to recreate stuff that is likely just "garbage in means garbage out" anyway.

I realized last night, it looks like all the vomit problems in "on display update" most likely stem from issues further back in the event chain. I mean I was / We were seeing a "boost error" because "is not None" was passing "lost weakref" references to the midi feedback mapper methods; but after I switched to using liveobj_valid() instead I started seeing vomit from "on display update" until I fixed the same issue "again" by using if not liveobj_valid(param) protection back in the midi mapper method (but not before fixing that other "on display update" issue with "error text" to display and then making the realization/connection here. "on display update" only vomits when some "lost weakref" is treated like a valid Live object))


Ok - I pushed up another commit to the encodermaphistory branch. I think I might have made a pretty good incursion on the device front. Everything I talked about above should be resolved now, or at least my limited testing indicates it could be so. Even deleting a device seems to be handled correctly. But I haven't done any extensive testing yet. Maybe tomorrow...

If you're interested, you might try to follow along, see if you can duplicate the behavior I reported, before you Pull in my latest commits, or whatever.

markusschloesser commented 3 years ago
  • no problems with device parameter mapping and feedback for the Wavetable device on the selected track at session startup. It loads correctly and the encoder click goes to device mode where the encoder twists work, and banking to the next page of parameters works.

yep, works here as well

    • however this is after the LCDs "settle down" after session startup. I mean, the first part is only visible if you power cycle the C4 so the "destroy message" disappears (shows nothing or the default Mackie message), for me; every time I start Live and the default session loads, it takes 3 screen updates for the C4 to "settle down". The first thing The LCDs show is the "Ableton Live offline" message, then the "default Mackie" message (again?), then finally, the "script's default view". Does that happen for you?

nope, nothing like that, can you make a screenshot or video? My display is fine

  • Add a Looper device and the event "update mapping" seems to work correctly. Encoder twists are mapped correctly. ...But, use the mouse to change the selected device (back to Wavetable) and the script doesn't keep up. ...until you use the Slot Up and/or Slot down buttons on the C4 to change "selected devices" a time or two to help the script get back on the rails. After that, you can use the mouse or the slot buttons to change selected track and the only thing that doesn't keep up with the mouse is the top LCD "selected device name" (and index) display.

works here, BUT somethings funky when switching on the C4 from chan strip to track/device mode. MOST of the times, it selects the first device on a track, even when another one was selected in Live (e.g. Device number 4). And selecting a different device in Live updates params and param names but Device name in top row is not properly updated.

    • however, if I go to the second parameter page of the Wavetable device, then use the mouse to switch selected device, the C4 shows an "empty" bank 2 of the selected Looper device, and that I can "bank left" to page 1 of the Looper parameters. If I do "bank left" to get to the actual Looper parameters, and then mouse-select the Wavetable device again, it is no longer mapped to parameter bank page 2. But it is properly mapped and responsive to parameter page 1 again.
    • it's seeming like the mapping and "event following" happens correctly when I use the C4 to trigger the "select device" events. It's only going off and staying off the rails following mouse events, and then going back on following (sometimes 2 or 3?) C4 triggered events.

Works here most of the times, but see above

Are you also seeing this same behavior? What else?

removing any device still causes vomits (old commit), but selecting another device or a track with a device on it, stops that.

(Don't go too far down the rabbit hole of writing down in detail what happens more than a few "bugs" beyond session startup. It's certainly ok to fix stuff as you encounter it if you want. I just mean since the "garbage in means garbage out" principle applies, don't burn a lot of cycles describing how to recreate stuff that is likely just "garbage in means garbage out" anyway.

I realized last night, it looks like all the vomit problems in "on display update" most likely stem from issues further back in the event chain. I mean I was / We were seeing a "boost error" because "is not None" was passing "lost weakref" references to the midi feedback mapper methods; but after I switched to using liveobj_valid() instead I started seeing vomit from "on display update" until I fixed the same issue "again" by using if not liveobj_valid(param) protection back in the midi mapper method (but not before fixing that other "on display update" issue with "error text" to display and then making the realization/connection here. "on display update" only vomits when some "lost weakref" is treated like a valid Live object))

makes total sense.

  • adding the first device after session load always seems to increment the channel mode "current device bank" instead of only when "current device bank" is already "full" (with 8 devices). Need to repeat a few times, maybe, but it looks like without even going to device mode yet, when I go from one device to two devices on the session-default track, the C4 shows I can "bank left", when I do I see both the original and the new device.
    • Oh wow... whatever I just changed combined with "banking back" so channel mode shows the correct display info seems to have completely resolved the weird differences I was describing above between changing selected devices with the mouse versus the C4.
    • Interesting. it's not just the first time a device is added in channel mode. Even after "banking back" to see the 2 devices, adding a third device (Gate) "erases" the device names view and shows you that you can "bank left". What warrants interest is "hardly anything is logged" when clicking to actually "bank left" initially and "nothing happens" in response. You can (I did) click several times in a row eventually to confirm only a couple of seemingly unrelated log lines appear. UNTIL someone like me clicks the dark "bank right" encoder button anyway out of frustration, after which can't increment selected_device_bank_index: already on last bank gets logged, which appears to act like keys to this particular kingdom, because now suddenly "something happens" in response to "bank left"... and then, "banking left" to see the devices on the track in channel mode only "sticks" or "appears" after you use the C4 to change selected device once (Single Parameter button down low). When you use the mouse to change selections, until you use the C4, the display "resets" and freezes "bank left" again.

Ok - I pushed up another commit to the encodermaphistory branch. I think I might have made a pretty good incursion on the device front. Everything I talked about above should be resolved now, or at least my limited testing indicates it could be so. Even deleting a device seems to be handled correctly. But I haven't done any extensive testing yet. Maybe tomorrow...

will check later today!

If you're interested, you might try to follow along, see if you can duplicate the behavior I reported, before you Pull in my latest commits, or whatever.

markusschloesser commented 3 years ago

newest commit: selecting master track when in device mode throws:

RemoteScriptError:   File "C:\ProgramData\Ableton\Live 11 Beta\Resources\MIDI Remote Scripts\MackieC4\MackieC4.py", line 381, in track_change
RemoteScriptError: self.__encoder_controller.track_changed(selected_index)
RemoteScriptError:   File "C:\ProgramData\Ableton\Live 11 Beta\Resources\MIDI Remote Scripts\MackieC4\EncoderController.py", line 164, in track_changed
RemoteScriptError: self.__eah.update_device_counter(track_index, 0)
RemoteScriptError:   File "C:\ProgramData\Ableton\Live 11 Beta\Resources\MIDI Remote Scripts\MackieC4\EncoderAssignmentHistory.py", line 81, in update_device_counter
RemoteScriptError: self.t_d_count[t] = d
RemoteScriptError: IndexError
RemoteScriptError: list assignment index out of range

going to chan strip after that shows lots of ZZZZZ and zzz with:

RemoteScriptError:   File "C:\ProgramData\Ableton\Live 11 Beta\Resources\MIDI Remote Scripts\MackieC4\MackieC4.py", line 214, in receive_midi
RemoteScriptError: self.__encoder_controller.handle_assignment_switch_ids(note)
RemoteScriptError:   File "C:\ProgramData\Ableton\Live 11 Beta\Resources\MIDI Remote Scripts\MackieC4\EncoderController.py", line 424, in handle_assignment_switch_ids
RemoteScriptError: self.__reassign_encoder_parameters(for_display_only=False)
RemoteScriptError:   File "C:\ProgramData\Ableton\Live 11 Beta\Resources\MIDI Remote Scripts\MackieC4\EncoderController.py", line 907, in __reassign_encoder_parameters
RemoteScriptError: self.__eah.set_max_device_count(current_nbr_of_devices_on_selected_track)
RemoteScriptError:   File "C:\ProgramData\Ableton\Live 11 Beta\Resources\MIDI Remote Scripts\MackieC4\EncoderAssignmentHistory.py", line 438, in set_max_device_count
RemoteScriptError: self.t_d_count[self.t_current] = max_device_count
RemoteScriptError: IndexError
RemoteScriptError: list assignment index out of range
markusschloesser commented 3 years ago

newest commit: deleting last device only throws ONE error:

RemoteScriptError:   File "C:\ProgramData\Ableton\Live 11 Beta\Resources\MIDI Remote Scripts\MackieC4\MackieC4.py", line 932, in <lambda>
RemoteScriptError: cb = lambda: self.device_changestate(track, tid, type)
RemoteScriptError:   File "C:\ProgramData\Ableton\Live 11 Beta\Resources\MIDI Remote Scripts\MackieC4\MackieC4.py", line 940, in device_changestate
RemoteScriptError: self.__encoder_controller.device_added_deleted_or_changed(track, tid, type)
RemoteScriptError:   File "C:\ProgramData\Ableton\Live 11 Beta\Resources\MIDI Remote Scripts\MackieC4\EncoderController.py", line 279, in device_added_deleted_or_changed
RemoteScriptError: self.__chosen_plugin = self.selected_track.devices[updated_idx]  # == new selected device
RemoteScriptError: IndexError
RemoteScriptError: Index out of range

deleting any device when there are still devices left, does NOT throw an error! :-)

markusschloesser commented 3 years ago

2 other bugs:

  1. I can arm tracks which have no valid input which obviously throws an error, I can look into that
  2. script doesn't properly disconnect
BilldarBagdar commented 3 years ago

Hmmm. Ok Master Track. I had not checked that yet, I was only looking at the "regular tracks". But now that you mention it, the index of the master track is not necessarily considered when device events are processed. The only tracks that get passed in are visibleTracks() + returnTracks() not also the Master track.

Arming/muting/(soloing?) tracks, or the display thereof, is something I want to change from mostly being hard coded in "on display update" to using the "architecture" we now have in place like EncoderDisplaySegment.

Overall, this isn't too bad. I should have a push ready in a few hours (if I don't get distracted too much again...)

markusschloesser commented 3 years ago

Check https://github.com/markusschloesser/MackieC4_P3/issues/58#issuecomment-827196551 for encoderdisplaysegment stuff in framework

BilldarBagdar commented 3 years ago

yes, stuff like that too. I'll post over there too I guess, but ultimately I would rather see that adjust_string() method call "built-in" to the EncoderDisplaySegment class methods. "Ultimately" (in my head currently) "on display update" should just iterate through the 32 "display segments" currently stored, concatenate their lower and upper text in strings for each LCD and display those strings. All the "smarts" about what to display in what mode and if shift is pressed or whatever should have already filtered the "text to display" so "on display update" is really only concerned with assembling the sysex messages containing the (displayable only) text for each LCD. Of course, engineering all that will likely involve building some way to aggregate "display segments" into collections of (LCD length) 8 "display segments" so all the longer messages like the offline message can be displayed properly if/when just iterating through the 32 "display segments" currently stored.

markusschloesser commented 3 years ago

yes, stuff like that too. I'll post over there too I guess, but ultimately I would rather see that adjust_string() method call "built-in" to the EncoderDisplaySegment class methods.

But just the call, not the code, right?

"Ultimately" (in my head currently) "on display update" should just iterate through the 32 "display segments" currently stored, concatenate their lower and upper text in strings for each LCD and display those strings. All the "smarts" about what to display in what mode and if shift is pressed or whatever should have already filtered the "text to display" so "on display update" is really only concerned with assembling the sysex messages containing the (displayable only) text for each LCD. Of course, engineering all that will likely involve building some way to aggregate "display segments" into collections of (LCD length) 8 "display segments" so all the longer messages like the offline message can be displayed properly if/when just iterating through the 32 "display segments" currently stored.

Did you accept the invitation to the other live script repo? Because I have recently updated it and it now includes docstrings for lots of things. And what you wanna do, is l already there in the framework code 😉

BilldarBagdar commented 3 years ago

yeah yeah, substituting in that "library" method call for a "reinventing the wheel" custom method is well advised. I just meant moving "any" of that kind of text manipulation behind get_upper_text() and get_lower_text(), for example, and out of "on display update".

I'm sorry, I did not attempt accepting that invitation again until it had already expired again. I don't always check every email address consistently. Try this maybe. Send another invitation, and follow it up by posting a new link to something in the repo I can click on here. I should be able to accept the invitation right here on GitHub if/when following the link before the invitation expires.

In general I agree about moving in the direction of "the framework way". But I also know I won't necessarily personally understand what I see reading through the framework code can replace what is in the script code before I understand what the script does to begin with. So, I won't be leading the charge, I work at more of a tortoise pace. :) I'm understanding a little bit more with each successful fix (and refactor) I put in, and each little bit of understanding adds to confidence toward bigger changes and ideas. I know there's tons of "future opportunity", but my Python skills are very rudimentary compared to, for example, (I will come back and edit in his correct name :)). His remote script code looks like he absolutely has a command of the Python language (and much more) that I can only dream of at this point. In a way, it's fortunate for me this C4 script is written so "old school" and custom to begin with. (and has so many little problems to repair)

markusschloesser commented 3 years ago

I'm sorry, I did not attempt accepting that invitation again until it had already expired again. I don't always check every email address consistently. Try this maybe. Send another invitation, and follow it up by posting a new link to something in the repo I can click on here. I should be able to accept the invitation right here on GitHub if/when following the link before the invitation expires.

done! And https://github.com/markusschloesser/AbletonRemoteScriptsPY/blob/main/ableton/v2/control_surface/elements/physical_display.py

BilldarBagdar commented 3 years ago

cool.

I just pushed a fresh update to "encodermaphistory" origin. selecting and putting devices on/off the master track should be working, and I hopefully finally completely fixed deleting the only device on a track. That 555 in particular was a perfect error signal in that respect. When you told me all you did was select the master track and the "track index" that appeared in the error message was 555, I knew that was my little easter egg hatching.

One thing we are going to need to do for a "release version" is remove our own "log vomit". It's great and very helpful to us as we develop, but it's mostly noise and pollution spewing from "release code".

BilldarBagdar commented 3 years ago

This looks like an example of how one would actually use a "physical display element" reference from the file linked above. But I'm not at a level where I know how to take that example and run. I also found references to a "Numerical display element" that could be useful at some point.

BTW - I found that reference to elements.py by searching in my local collection of those same files (from Live 10) within PyCharm.

Edit: Continuing

I can arm tracks which have no valid input which obviously throws an error

I tried to duplicate this and at first I couldn't tell what you meant. I mean I am still guessing, but I found 2 different problems related to the mapped and displayed "last 4 encoders" including the "Rec Arm" encoder in channel mode.

The most closely related thing I found is that it looks like the "can_be_armed" property (the way we are using it) doesn't seem to always/ever? account for the "monitoring status" of a track at runtime. If Monitoring is "turned off", for example, the C4 still shows a "Record Arm" encoder that seems to be mapped like normal, and we only show "record arm" if "can_be_armed" reports true. But I can only get the LED ring to light up once on the first click, and no errors in the log. I can switch tracks back and forth between audio, midi, return, master, and a "monitoring off" track, and every time I land on the "monitoring off" track, all I can do is "enlighten the poti" once. How do you make errors happen? (also, make sure you are on my latest commit to origin, or I could be talking apples when you are seeing oranges) I'm thinking it would be cool to display "disabl" or something besides ON or OFF when its not "currently" armable for a track.

The other thing I found is that for tracks that you can never arm, like Returns or Master, the C4 display doesn't show a "Rec Arm" encoder. However there is a problem related to "skipping" the "Rec Arm" encoder (because the track can never be armed ever?). It looks like encoders 30, 31, and 32 are still correctly mapped for feedback, but the display segments are shifted left. When I turn encoder 32 (vol) the display over encoder 31 show the volume feedback. What would be the "Rec Arm" encoder shows "Mute On/Off" over it and doesn't enlighten or throw errors when pressed.

Something I noticed is that the two issues above seem to be related because whatever I described in the first part above only seems to occur after loading a session up. Once a certain event occurs, what I was observing/describing doesn't occur any longer. This is the trigger I think. When a session first loads and you select a return track, it shows 2 "volume displays" The last one always (in my case) shows 0.0 as the volume level, and the other one shows "real feedback". If you then select an audio track and turn "Monitoring Off", you should see the one-click wonder on "Rec Arm" presses. If you next set the Track Input to "No Input", the track "effectively" turns into a return track for display purposes. The same "shift left" of the display problem for return tracks appears here with the same static 0.0 value over encoder 32. But (double check the volume is above or below 0.0) then, select an audio input again on that track and then go select a return track again. Now that static 0.0 value over 32 is gone, now the static value is whatever the volume was on that track for which you just re-enabled the audio input.

After the "static value" showing for return tracks (and similar status) is no longer 0.0 (more correctly no longer the "first after session loads" value), the "Rec Arm" issue (whatever it is) when "Monitoring is off" is no longer apparent.