Push 2 Scales
-
- Posts: 7
- Joined: Wed May 08, 2013 10:51 am
- Contact:
Re: Push 2 Scales
Just confirming that this also works with Live 11 beta.
Note however that, although that the newly added scales will still show up in Push, they won't be present in the new 'Scales' list shown in the new MIDI clip editor.
Note however that, although that the newly added scales will still show up in Push, they won't be present in the new 'Scales' list shown in the new MIDI clip editor.
-
- Posts: 35
- Joined: Thu Feb 08, 2018 9:29 am
Re: Push 2 Scales
You spoke too soon I think, I repeatedly get this error and/or just a blank screen on the push and nothing but the dot on the pitch bend lighting up in the latest beta 11.0b22MauriceNorris wrote: ↑Wed Nov 11, 2020 9:30 amJust confirming that this also works with Live 11 beta.
Note however that, although that the newly added scales will still show up in Push, they won't be present in the new 'Scales' list shown in the new MIDI clip editor.

Any anyone please look into why this is happening all of a sudden? Almost looks like a deliberate thing done by Ableton to stop us from upgrading the push like that or what? This looks like deliberate tampering to make it not work all of a sudden, but please prove me wrong or find a way to circumvent this nonsense. Thanks


Re: Push 2 Scales
L11 now uses v3 of Python, and 3rd party scripts need to be updated to work with it.
Ableton Forum Moderator
-
- Posts: 7
- Joined: Wed May 08, 2013 10:51 am
- Contact:
Re: Push 2 Scales
Hmm, that's strange. I'm on b23 and am not getting this error at all. The modified melodic_pattern.py is still working fine.torbenscharling wrote: ↑Mon Dec 21, 2020 5:36 am
You spoke too soon I think, I repeatedly get this error and/or just a blank screen on the push and nothing but the dot on the pitch bend lighting up in the latest beta 11.0b22![]()
-
- Posts: 35
- Joined: Thu Feb 08, 2018 9:29 am
Re: Push 2 Scales
I'm on 23 now and still does it..Push 2 logo on the push and ableton says Script could not be loadedMauriceNorris wrote: ↑Sun Jan 17, 2021 8:55 pmHmm, that's strange. I'm on b23 and am not getting this error at all. The modified melodic_pattern.py is still working fine.torbenscharling wrote: ↑Mon Dec 21, 2020 5:36 am
You spoke too soon I think, I repeatedly get this error and/or just a blank screen on the push and nothing but the dot on the pitch bend lighting up in the latest beta 11.0b22![]()
Did you compile it fresh with the 11 install or just copy paste it over from the one in the 10 pushbase?
If it works on yours why does it keep saying remote script doesnt work on mine?
Works fine on ableton 10 beta still...same push, same machine..doesn't work on 11 beta 22 and 11 beta 23..
I don't know much about compiling pyc files and stuff like that I just want additional scales to work like they do on 10, since I payed for the upgrade to 11, so far I'm stuck with the info that it needs to be updated to python 3 but if that's not the case, the original "dev" doesn't have to be bothered making a new .pyc or if I can just change something manually in it, but I need to know where to go from here to fix this issue.
-
- Posts: 7
- Joined: Wed May 08, 2013 10:51 am
- Contact:
Re: Push 2 Scales
@torbenscharling
I didn't compile it, no. You don't need to. Ableton does the compiling for you (from the .py file)
I just copied the melodic_pattern.py from the Live 10 to Live 11.
Are you copying the .py or the .pyc file to Ableton 11? If it's the .pyc then this will almost certainly produce an error as this is the file that Ableton 10 has already compiled. Ableton needs to 'see' the .py file and then compile it itself.
You're welcome to use my melodic_pattern.py though if you like? You can download it here:
https://drive.google.com/file/d/1Sm-0Ze ... sp=sharing
Just make sure you backup your original melodic_pattern.pyc (which I'm guessing you already have) and delete the melodic_pattern.pyc script that isn't working for you. If it's working for you (and I can't see any reason it shouldn't) you should just be able to copy the part where you define the scales from your old script into mine.
Hope this helps.
I didn't compile it, no. You don't need to. Ableton does the compiling for you (from the .py file)
I just copied the melodic_pattern.py from the Live 10 to Live 11.
Are you copying the .py or the .pyc file to Ableton 11? If it's the .pyc then this will almost certainly produce an error as this is the file that Ableton 10 has already compiled. Ableton needs to 'see' the .py file and then compile it itself.
You're welcome to use my melodic_pattern.py though if you like? You can download it here:
https://drive.google.com/file/d/1Sm-0Ze ... sp=sharing
Just make sure you backup your original melodic_pattern.pyc (which I'm guessing you already have) and delete the melodic_pattern.pyc script that isn't working for you. If it's working for you (and I can't see any reason it shouldn't) you should just be able to copy the part where you define the scales from your old script into mine.
Hope this helps.
-
- Posts: 35
- Joined: Thu Feb 08, 2018 9:29 am
Re: Push 2 Scales
Indeed it does help tremendously !!! THANKS SO MUCH !! This has been bugging the h... out of me cause I couldn't get ableton support on this so I had no idea if I could safely upgrade to 11 and had to do it in time to get the 20% discount so now I got both bases covered so I'm ready for when 11 is released (apart from reading the damn manual lol) anyway thanks again, now I don't have to worry so much about what happened. But just in case anyone has a clue what went wrong (I'm pretty sure I did the same, copying over the .py file) so here it is copy pasted (the one giving me the error consistently):MauriceNorris wrote: ↑Wed Jan 20, 2021 2:59 pm@torbenscharling
I didn't compile it, no. You don't need to. Ableton does the compiling for you (from the .py file)
I just copied the melodic_pattern.py from the Live 10 to Live 11.
Are you copying the .py or the .pyc file to Ableton 11? If it's the .pyc then this will almost certainly produce an error as this is the file that Ableton 10 has already compiled. Ableton needs to 'see' the .py file and then compile it itself.
You're welcome to use my melodic_pattern.py though if you like? You can download it here:
https://drive.google.com/file/d/1Sm-0Ze ... sp=sharing
Just make sure you backup your original melodic_pattern.pyc (which I'm guessing you already have) and delete the melodic_pattern.pyc script that isn't working for you. If it's working for you (and I can't see any reason it shouldn't) you should just be able to copy the part where you define the scales from your old script into mine.
Hope this helps.
# uncompyle6 version 3.7.0
# Python bytecode 2.7 (62211)
# Decompiled from: Python 2.7.16 (v2.7.16:413a49145e, Mar 4 2019, 01:37:19) [MSC v.1500 64 bit (AMD64)]
# Embedded file name: c:\Jenkins\live\output\Live\win_64_static\Release\python-bundle\MIDI Remote Scripts\pushbase\melodic_pattern.py
# Compiled at: 2020-01-07 14:24:16
from __future__ import absolute_import, print_function, unicode_literals
from ableton.v2.base import NamedTuple, lazy_attribute, memoize, find_if
from . import consts
from .matrix_maps import FEEDBACK_CHANNELS
import Live
CIRCLE_OF_FIFTHS = tuple([ 7 * k % 12 for k in range(12) ])
ROOT_NOTES = CIRCLE_OF_FIFTHS[0:6] + CIRCLE_OF_FIFTHS[-1:5:-1]
NOTE_NAMES = (u'C', u'D\u266d', u'D', u'E\u266d', u'E', u'F', u'G\u266d', u'G', u'A\u266d',
u'A', u'B\u266d', u'B')
def pitch_index_to_string(index):
if 0 <= index < 128:
return NOTE_NAMES[(index % 12)] + str(index / 12 - 2)
return consts.CHAR_ELLIPSIS
class Scale(NamedTuple):
name = ''
notes = []
def to_root_note(self, root_note):
return Scale(name=NOTE_NAMES[root_note], notes=[ root_note + x for x in self.notes ])
@memoize
def scale_for_notes(self, notes):
return [ self.to_root_note(b) for b in notes ]
def __unicode__(self):
return self.name
def __str__(self):
return unicode(self).encode('utf-8')
def __eq__(self, other):
if isinstance(other, Scale):
return self.name == other.name and self.notes == other.notes
return False
EXTRA_SCALES = (
("ionian pentatonic", (0, 4, 5, 7, 11)),
("mixolydian pent.", (0, 4, 5, 7, 10)),
("ritusen", (0, 2, 5, 7, 9)),
("egyptian", (0, 2, 5, 7, 10)),
("neo. major pent.", (0, 4, 5, 6, 10)),
("vietnamese 1", (0, 3, 5, 7,

("lydian pentatonic", (0, 4, 6, 7, 11)),
("malkos raga", (0, 3, 5, 8, 10)),
("locrian pentatonic", (0, 3, 5, 6, 10)),
("minor six pent.", (0, 3, 5, 7, 9)),
("flat six pent.", (0, 2, 4, 7,

("scriabin", (0, 1, 4, 7, 9)),
("whole tone pent.", (0, 4, 6, 8, 10)),
("lydian #5P pent.", (0, 4, 6, 8, 11)),
("lydian dom. pent.", (0, 4, 6, 7, 10)),
("minor #7M pent.", (0, 3, 5, 7, 11)),
("sup. locrian pent.", (0, 3, 4, 6, 10)),
("minor hexatonic", (0, 2, 3, 5, 7, 11)),
("augmented", (0, 3, 4, 7, 8, 11)),
("major blues", (0, 2, 3, 4, 7, 9)),
("piongio", (0, 2, 5, 7, 9, 10)),
("prometheus neo.", (0, 1, 4, 6, 9, 10)),
("prometheus", (0, 2, 4, 6, 9, 10)),
("mystery #1", (0, 1, 4, 6, 8, 10)),
("6-tone symmetric", (0, 1, 4, 5, 8, 9)),
("locrian major", (0, 2, 4, 5, 6, 8, 10)),
("dbl. harm. lydian", (0, 1, 4, 6, 7, 8, 11)),
("locrian #2", (0, 2, 3, 5, 6, 8, 10)),
("mixolydian b6", (0, 2, 4, 5, 7, 8, 10)),
("dorian b2", (0, 1, 3, 5, 7, 9, 10)),
("ultralocrian", (0, 1, 3, 4, 6, 8, 9)),
("locrian 6", (0, 1, 3, 5, 6, 9, 10)),
("augmented hep.", (0, 3, 4, 5, 7, 8, 11)),
("lydian diminished", (0, 2, 3, 6, 7, 9, 11)),
("lead. whole tone", (0, 2, 4, 6, 8, 10, 11)),
("lydian minor", (0, 2, 4, 6, 7, 8, 10)),
("balinese", (0, 1, 3, 5, 7, 8, 11)),
("neopolitan major", (0, 1, 3, 5, 7, 9, 11)),
("hungarian major", (0, 3, 4, 6, 7, 9, 10)),
("oriental", (0, 1, 4, 5, 6, 9, 10)),
("flamenco", (0, 1, 3, 4, 6, 7, 10)),
("todi raga", (0, 1, 3, 6, 7, 8, 11)),
("persian", (0, 1, 4, 5, 6, 8, 11)),
("enigmatic", (0, 1, 4, 6, 8, 10, 11)),
("major augmented", (0, 2, 4, 5, 8, 9, 11)),
("lydian #9", (0, 3, 4, 6, 7, 9, 11)),
("purvi raga", (0, 1, 4, 5, 6, 7, 8, 11)),
("spanish hept.", (0, 1, 3, 4, 5, 7, 8, 10)),
("bebop", (0, 2, 4, 5, 7, 9, 10, 11)),
("bebop minor", (0, 2, 3, 4, 5, 7, 9, 10)),
("bebop major", (0, 2, 4, 5, 7, 8, 9, 11)),
("bebop locrian", (0, 1, 3, 5, 6, 7, 8, 10)),
("minor bebop", (0, 2, 3, 5, 7, 8, 10, 11)),
("ichikosucho", (0, 2, 4, 5, 6, 7, 9, 11)),
("minor six dim.", (0, 2, 3, 5, 7, 8, 9, 11)),
("kafi raga", (0, 3, 4, 5, 7, 9, 10, 11)),
("composite blues", (0, 2, 3, 4, 5, 6, 7, 9, 10))
)
SCALES = tuple([ Scale(name=x[0], notes=x[1]) for x in Live.Song.get_all_scales_ordered() + EXTRA_SCALES ])
def scale_by_name(name):
return find_if(lambda m: m.name == name, SCALES)
class NoteInfo(NamedTuple):
index = None
channel = 0
color = 'NoteInvalid'
class MelodicPattern(NamedTuple):
steps = [
0, 0]
scale = range(12)
root_note = 0
origin = [0, 0]
chromatic_mode = False
width = None
height = None
@lazy_attribute
def extended_scale(self):
if self.chromatic_mode:
first_note = self.scale[0]
return range(first_note, first_note + 12)
else:
return self.scale
@property
def is_aligned(self):
return not self.origin[0] and not self.origin[1] and abs(self.root_note) % 12 == self.extended_scale[0]
def note(self, x, y):
if not self._boundary_reached(x, y):
channel = y % len(FEEDBACK_CHANNELS) + FEEDBACK_CHANNELS[0]
return self._get_note_info(self._octave_and_note(x, y), self.root_note, channel)
return NoteInfo()
def __getitem__(self, i):
root_note = self.root_note
if root_note <= -12:
root_note = 0 if self.is_aligned else -12
return self._get_note_info(self._octave_and_note_linear(i), root_note)
def _boundary_reached(self, x, y):
return self.width is not None and x >= self.width or self.height is not None and y >= self.height
def _octave_and_note_by_index(self, index):
scale = self.extended_scale
scale_size = len(scale)
octave = index / scale_size
note = scale[(index % scale_size)]
return (octave, note)
def _octave_and_note(self, x, y):
index = self.steps[0] * (self.origin[0] + x) + self.steps[1] * (self.origin[1] + y)
return self._octave_and_note_by_index(index)
def _color_for_note(self, note):
if note == self.scale[0]:
return 'NoteBase'
else:
if note in self.scale:
return 'NoteScale'
return 'NoteNotScale'
def _get_note_info(self, (octave, note), root_note, channel=0):
note_index = 12 * octave + note + root_note
if 0 <= note_index <= 127:
return NoteInfo(index=note_index, channel=channel, color=self._color_for_note(note))
else:
return NoteInfo()
def _octave_and_note_linear(self, i):
origin = self.origin[0] or self.origin[1]
index = origin + i
return self._octave_and_note_by_index(index)
-
- Posts: 7
- Joined: Wed May 08, 2013 10:51 am
- Contact:
Re: Push 2 Scales
@torbenscharling
No worries! Glad you got it working in the end
There do seem to be quite a few differences in the script that wasn't working for you and the one that is, although I don't know enough about Python to know what these differences actually mean!
Here's the working one for reference if anyone else needs it:
No worries! Glad you got it working in the end

There do seem to be quite a few differences in the script that wasn't working for you and the one that is, although I don't know enough about Python to know what these differences actually mean!
Here's the working one for reference if anyone else needs it:
Code: Select all
# uncompyle6 version 3.6.4
# Python bytecode 2.7 (62211)
# Decompiled from: Python 2.7.17 (default, Sep 30 2020, 13:38:04)
# [GCC 7.5.0]
# Embedded file name: /Users/versonator/Jenkins/live/output/Live/mac_64_static/Release/python-bundle/MIDI Remote Scripts/pushbase/melodic_pattern.py
# Compiled at: 2020-11-06 11:19:13
from __future__ import absolute_import, print_function, unicode_literals
from __future__ import division
from builtins import str
from builtins import range
from past.utils import old_div
from ableton.v2.base import NamedTuple, lazy_attribute, memoize, find_if
from . import consts
from .matrix_maps import FEEDBACK_CHANNELS
import Live
CIRCLE_OF_FIFTHS = tuple([ 7 * k % 12 for k in range(12) ])
ROOT_NOTES = CIRCLE_OF_FIFTHS[0:6] + CIRCLE_OF_FIFTHS[-1:5:-1]
NOTE_NAMES = (u'C', u'D\u266d', u'D', u'E\u266d', u'E', u'F', u'G\u266d', u'G', u'A\u266d',
u'A', u'B\u266d', u'B')
def pitch_index_to_string(index):
if index is not None and 0 <= index < 128:
return NOTE_NAMES[(index % 12)] + str(old_div(index, 12) - 2)
else:
return consts.CHAR_ELLIPSIS
class Scale(NamedTuple):
name = ''
notes = []
def to_root_note(self, root_note):
return Scale(name=NOTE_NAMES[root_note], notes=[ root_note + x for x in self.notes ])
@memoize
def scale_for_notes(self, notes):
return [ self.to_root_note(b) for b in notes ]
def __unicode__(self):
return self.name
def __str__(self):
return str(self.name)
def __eq__(self, other):
if isinstance(other, Scale):
return self.name == other.name and self.notes == other.notes
return False
def __hash__(self):
return hash((self.name,))
EXTRA_SCALES = (
("Ionian Pentatonic", (0, 4, 5, 7, 11)),
("Mixolydian Pent.", (0, 4, 5, 7, 10)),
("Ritusen", (0, 2, 5, 7, 9)),
("Egyptian", (0, 2, 5, 7, 10)),
("Neo. Major Pent.", (0, 4, 5, 6, 10)),
("Vietnamese 1", (0, 3, 5, 7, 8)),
("Lydian Pentatonic", (0, 4, 6, 7, 11)),
("Malkos Raga", (0, 3, 5, 8, 10)),
("Locrian Pentatonic", (0, 3, 5, 6, 10)),
("Minor Six Pent.", (0, 3, 5, 7, 9)),
("Flat Six Pent.", (0, 2, 4, 7, 8)),
("Scriabin", (0, 1, 4, 7, 9)),
("Whole Tone Pent.", (0, 4, 6, 8, 10)),
("Lydian #5P Pent.", (0, 4, 6, 8, 11)),
("Lydian Dom. Pent.", (0, 4, 6, 7, 10)),
("Minor #7M Pent.", (0, 3, 5, 7, 11)),
("Sup. Locrian Pent.", (0, 3, 4, 6, 10)),
("Minor Hexatonic", (0, 2, 3, 5, 7, 11)),
("Augmented", (0, 3, 4, 7, 8, 11)),
("Major Blues", (0, 2, 3, 4, 7, 9)),
("Piongio", (0, 2, 5, 7, 9, 10)),
("Prometheus Neo.", (0, 1, 4, 6, 9, 10)),
("Prometheus", (0, 2, 4, 6, 9, 10)),
("Mystery #1", (0, 1, 4, 6, 8, 10)),
("6-tone Symmetric", (0, 1, 4, 5, 8, 9)),
("Locrian Major", (0, 2, 4, 5, 6, 8, 10)),
("Dbl. Harm. Lydian", (0, 1, 4, 6, 7, 8, 11)),
("Locrian #2", (0, 2, 3, 5, 6, 8, 10)),
("Mixolydian B6", (0, 2, 4, 5, 7, 8, 10)),
("Dorian B2", (0, 1, 3, 5, 7, 9, 10)),
("Ultralocrian", (0, 1, 3, 4, 6, 8, 9)),
("Locrian 6", (0, 1, 3, 5, 6, 9, 10)),
("Augmented Hep.", (0, 3, 4, 5, 7, 8, 11)),
("Lydian Diminished", (0, 2, 3, 6, 7, 9, 11)),
("Lead. Whole Tone", (0, 2, 4, 6, 8, 10, 11)),
("Lydian Minor", (0, 2, 4, 6, 7, 8, 10)),
("Balinese", (0, 1, 3, 5, 7, 8, 11)),
("Neopolitan Major", (0, 1, 3, 5, 7, 9, 11)),
("Hungarian Major", (0, 3, 4, 6, 7, 9, 10)),
("Oriental", (0, 1, 4, 5, 6, 9, 10)),
("Flamenco", (0, 1, 3, 4, 6, 7, 10)),
("Todi Raga", (0, 1, 3, 6, 7, 8, 11)),
("Persian", (0, 1, 4, 5, 6, 8, 11)),
("Enigmatic", (0, 1, 4, 6, 8, 10, 11)),
("Major Augmented", (0, 2, 4, 5, 8, 9, 11)),
("Lydian #9", (0, 3, 4, 6, 7, 9, 11)),
("Purvi Raga", (0, 1, 4, 5, 6, 7, 8, 11)),
("Spanish Hept.", (0, 1, 3, 4, 5, 7, 8, 10)),
("Bebop", (0, 2, 4, 5, 7, 9, 10, 11)),
("Bebop Minor", (0, 2, 3, 4, 5, 7, 9, 10)),
("Bebop Major", (0, 2, 4, 5, 7, 8, 9, 11)),
("Bebop Locrian", (0, 1, 3, 5, 6, 7, 8, 10)),
("Minor Bebop", (0, 2, 3, 5, 7, 8, 10, 11)),
("Ichikosucho", (0, 2, 4, 5, 6, 7, 9, 11)),
("Minor Six Dim.", (0, 2, 3, 5, 7, 8, 9, 11)),
("Kafi Raga", (0, 3, 4, 5, 7, 9, 10, 11)),
("Composite Blues", (0, 2, 3, 4, 5, 6, 7, 9, 10))
)
SCALES = tuple([ Scale(name=x[0], notes=x[1]) for x in Live.Song.get_all_scales_ordered() + EXTRA_SCALES ])
def scale_by_name(name):
return find_if(lambda m: m.name == name, SCALES)
class NoteInfo(NamedTuple):
index = None
channel = 0
color = 'NoteInvalid'
class MelodicPattern(NamedTuple):
steps = [
0, 0]
scale = list(range(12))
root_note = 0
origin = [0, 0]
chromatic_mode = False
width = None
height = None
@lazy_attribute
def extended_scale(self):
if self.chromatic_mode:
first_note = self.scale[0]
return list(range(first_note, first_note + 12))
else:
return self.scale
@property
def is_aligned(self):
return not self.origin[0] and not self.origin[1] and abs(self.root_note) % 12 == self.extended_scale[0]
def note(self, x, y):
if not self._boundary_reached(x, y):
channel = y % len(FEEDBACK_CHANNELS) + FEEDBACK_CHANNELS[0]
return self._get_note_info(self._octave_and_note(x, y), self.root_note, channel)
return NoteInfo()
def __getitem__(self, i):
root_note = self.root_note
if root_note <= -12:
root_note = 0 if self.is_aligned else -12
return self._get_note_info(self._octave_and_note_linear(i), root_note)
def _boundary_reached(self, x, y):
return self.width is not None and x >= self.width or self.height is not None and y >= self.height
def _octave_and_note_by_index(self, index):
scale = self.extended_scale
scale_size = len(scale)
octave = old_div(index, scale_size)
note = scale[(index % scale_size)]
return (
octave, note)
def _octave_and_note(self, x, y):
index = self.steps[0] * (self.origin[0] + x) + self.steps[1] * (self.origin[1] + y)
return self._octave_and_note_by_index(index)
def _color_for_note(self, note):
if note == self.scale[0]:
return 'NoteBase'
else:
if note in self.scale:
return 'NoteScale'
return 'NoteNotScale'
def _get_note_info(self, octave_note, root_note, channel=0):
octave, note = octave_note
note_index = 12 * octave + note + root_note
if 0 <= note_index <= 127:
return NoteInfo(index=note_index, channel=channel, color=self._color_for_note(note))
else:
return NoteInfo()
def _octave_and_note_linear(self, i):
origin = self.origin[0] or self.origin[1]
index = origin + i
return self._octave_and_note_by_index(index)