From 92d52d4439be693a12f71eeb1606800fefabc5f1 Mon Sep 17 00:00:00 2001 From: Mark M Date: Tue, 12 Mar 2024 21:31:37 +0100 Subject: [PATCH 1/6] Cleanup: Rename to _parse_events_from_arranger_automation() --- dawtool/daw/ableton.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dawtool/daw/ableton.py b/dawtool/daw/ableton.py index 78ceaac..4b12937 100644 --- a/dawtool/daw/ableton.py +++ b/dawtool/daw/ableton.py @@ -254,7 +254,7 @@ def _calc_beat_real_time_fast_path(self): return self.tempo_automation_events is None or \ len(self.tempo_automation_events) == 1 - def _parse_arranger_automation_events(self, contents): + def _parse_events_from_arranger_automation(self, contents): """ Only for Ableton 8 and 9. """ @@ -281,7 +281,7 @@ def _parse_automation(self, contents): # Ableton 8, 9 store tempo auto differently if self.version.minorA < 10: - events = self._parse_arranger_automation_events(contents) + events = self._parse_events_from_arranger_automation(contents) else: if self.version.minorA in [10,11]: # This only applies to Ableton 10 and 11 @@ -318,7 +318,7 @@ def _parse_automation(self, contents): def _parse_tempo(self, contents): if self.version.minorA == 8: - events = self._parse_arranger_automation_events(contents) + events = self._parse_events_from_arranger_automation(contents) if not events: # there should always be at least 1 event in general, and especially # for Ableton 8. From 56ef7fd46a652b39c21ba9eae59444a32e50f923 Mon Sep 17 00:00:00 2001 From: Mark M Date: Tue, 12 Mar 2024 21:27:35 +0100 Subject: [PATCH 2/6] Test Live 12 support --- .../als/L12-automation-intense-unaligned.als | Bin 0 -> 5773 bytes tests/als/L12-automation.als | Bin 0 -> 5444 bytes tests/test_ableton.py | 25 ++++++++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 tests/als/L12-automation-intense-unaligned.als create mode 100644 tests/als/L12-automation.als diff --git a/tests/als/L12-automation-intense-unaligned.als b/tests/als/L12-automation-intense-unaligned.als new file mode 100644 index 0000000000000000000000000000000000000000..7429a2a733471aee5bde36d5713f4f2c9dbd3e53 GIT binary patch literal 5773 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 LBT~upP{RNKv1u?H literal 0 HcmV?d00001 diff --git a/tests/als/L12-automation.als b/tests/als/L12-automation.als new file mode 100644 index 0000000000000000000000000000000000000000..fd89dfdc760752792c76403f2a4e8fdf5eee8f70 GIT binary patch literal 5444 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 Date: Tue, 12 Mar 2024 21:34:54 +0100 Subject: [PATCH 3/6] Extract _parse_events_from_main_track() --- dawtool/daw/ableton.py | 61 +++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/dawtool/daw/ableton.py b/dawtool/daw/ableton.py index 4b12937..5ba42b5 100644 --- a/dawtool/daw/ableton.py +++ b/dawtool/daw/ableton.py @@ -272,6 +272,39 @@ def _parse_events_from_arranger_automation(self, contents): events = arranger_auto.find('Events') return events + def _parse_events_from_main_track(self, contents): + if self.version.minorA in [10,11]: + # This only applies to Ableton 10 and 11 + master_track_chunk = self._find_tag(contents, 'MasterTrack') + else: + # This only applies to Ableton 12 + master_track_chunk = self._find_tag(contents, 'MainTrack') + + try: + master_track = ET.fromstring(master_track_chunk) + except ParseError: + raise ValueError('Cannot parse automation') + + auto_envelopes = master_track.find('AutomationEnvelopes') + if auto_envelopes is None: + logger.warning('%s: No AutomationEnvelopes found in MasterTrack', self.filename) + return None + + envelopes = auto_envelopes.find('Envelopes') + if envelopes is None: + logger.warning('%s: No found in MasterTrack', self.filename) + return None + + events = None + + for env in envelopes: + pointee_id = env.find('EnvelopeTarget').find('PointeeId').get('Value') + if pointee_id == self.tempo_automation_target_id: + events = env.find('Automation').find('Events') + break + + return events + def _parse_automation(self, contents): """ Needs to be called after _parse_tempo @@ -283,33 +316,7 @@ def _parse_automation(self, contents): if self.version.minorA < 10: events = self._parse_events_from_arranger_automation(contents) else: - if self.version.minorA in [10,11]: - # This only applies to Ableton 10 and 11 - master_track_chunk = self._find_tag(contents, 'MasterTrack') - else: - # This only applies to Ableton 12 - master_track_chunk = self._find_tag(contents, 'MainTrack') - try: - master_track = ET.fromstring(master_track_chunk) - except ParseError: - raise ValueError('Cannot parse automation') - - auto_envelopes = master_track.find('AutomationEnvelopes') - if auto_envelopes is None: - logger.warning('%s: No AutomationEnvelopes found in MasterTrack', self.filename) - return - - envelopes = auto_envelopes.find('Envelopes') - if envelopes is None: - logger.warning('%s: No found in MasterTrack', self.filename) - return - - # events = None - for env in envelopes: - pointee_id = env.find('EnvelopeTarget').find('PointeeId').get('Value') - if pointee_id == self.tempo_automation_target_id: - events = env.find('Automation').find('Events') - break + events = self._parse_events_from_main_track(contents) if events is None: return From 4367c954eecb85df3659a9c5b6a10933695aae7f Mon Sep 17 00:00:00 2001 From: Mark M Date: Tue, 12 Mar 2024 21:47:16 +0100 Subject: [PATCH 4/6] Consolidate version checking in one place We could be defensive and raise an error if we detect e.g. Live 13. On the other hand, we could just try to parse it anyway and see if it works. I suspect this code might not change much, so there a chance Live 13 could be released and no action is required on our part. Of course it would be nice to add tests when that happens, but I'd rather not be so strict and guarantee that we break when L13 comes out. --- dawtool/daw/ableton.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/dawtool/daw/ableton.py b/dawtool/daw/ableton.py index 5ba42b5..4900634 100644 --- a/dawtool/daw/ableton.py +++ b/dawtool/daw/ableton.py @@ -272,13 +272,8 @@ def _parse_events_from_arranger_automation(self, contents): events = arranger_auto.find('Events') return events - def _parse_events_from_main_track(self, contents): - if self.version.minorA in [10,11]: - # This only applies to Ableton 10 and 11 - master_track_chunk = self._find_tag(contents, 'MasterTrack') - else: - # This only applies to Ableton 12 - master_track_chunk = self._find_tag(contents, 'MainTrack') + def _parse_events_from_main_track(self, contents, main_track_name): + master_track_chunk = self._find_tag(contents, main_track_name) try: master_track = ET.fromstring(master_track_chunk) @@ -316,7 +311,8 @@ def _parse_automation(self, contents): if self.version.minorA < 10: events = self._parse_events_from_arranger_automation(contents) else: - events = self._parse_events_from_main_track(contents) + main_track_name = 'MasterTrack' if self.version.minorA in (10, 11) else 'MainTrack' + events = self._parse_events_from_main_track(contents, main_track_name) if events is None: return From 57e8857af6a50caddd0d5ecf9736726150616596 Mon Sep 17 00:00:00 2001 From: Mark M Date: Tue, 12 Mar 2024 21:50:29 +0100 Subject: [PATCH 5/6] Cleanup: Remove redundant comment and stray line --- dawtool/daw/ableton.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/dawtool/daw/ableton.py b/dawtool/daw/ableton.py index 4900634..6a603e8 100644 --- a/dawtool/daw/ableton.py +++ b/dawtool/daw/ableton.py @@ -304,10 +304,8 @@ def _parse_automation(self, contents): """ Needs to be called after _parse_tempo """ - events = None - # Ableton 8, 9 store tempo auto differently if self.version.minorA < 10: events = self._parse_events_from_arranger_automation(contents) else: From 899b636a4645d391a757663f4dbb6459023ddbdb Mon Sep 17 00:00:00 2001 From: Mark M Date: Tue, 12 Mar 2024 21:51:48 +0100 Subject: [PATCH 6/6] README: Update supported Ableton Live versions --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aad36c7..48a23cc 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ It provides a high accuracy implementation of **time marker extraction**, including support for projects with tempo automation. Supported formats: -- Ableton Live set (.als) [v8-10] +- Ableton Live set (.als) [v8-12] - FL Studio project (.flp) [v10-11, 20] - Cue sheet (.cue)