diff --git a/compact_sets.py b/compact_sets.py index 7c258a5..3aabbbb 100644 --- a/compact_sets.py +++ b/compact_sets.py @@ -540,11 +540,20 @@ class HarmonicSpace: cents = abs(src_pitch.to_cents() - dst_pitch.to_cents()) cent_diffs.append(cents) - # Check voice_crossing: True if any voice moves to different position - num_voices = len(c1.pitches) - voice_crossing = not all( - movements.get(i, i) == i for i in range(num_voices) - ) + # Check voice_crossing: compare pitch ordering before/after + # Voice crossing = True if ordering changes (e.g., bass below tenor -> tenor below bass) + source = list(c1.pitches) + ordered_source = sorted(source, key=lambda p: p.to_fraction()) + source_order = [ordered_source.index(p) for p in source] + + # Destination pitches: transpose back to get sounding pitches + destination = [ + c2_transposed.pitches[movements[p]] for p in range(len(source)) + ] + ordered_destination = sorted(destination, key=lambda p: p.to_fraction()) + destination_order = [ordered_destination.index(p) for p in destination] + + voice_crossing = source_order != destination_order # Check is_directly_tunable: changing pitches are adjacent to staying pitch is_directly_tunable = self._is_directly_tunable(