Godtone
Joined 17 December 2020
→Novation Launchpad Pro MK3 isomorphic keyboard code: catalogue inconsistency error that may occur |
m →Novation Launchpad Pro MK3 isomorphic keyboard code: (note potential error) |
||
| (11 intermediate revisions by 2 users not shown) | |||
| Line 9: | Line 9: | ||
* [[User:Godtone/zeta]] | * [[User:Godtone/zeta]] | ||
Whose significance is backed up by the more psychoacoustically-informed tuning metrics I've designed (<code>optimal_edo_sequence</code>s from [[#My Python 3 code]]): | Whose significance is backed up by the more psychoacoustically-informed tuning metrics I've designed (<code>optimal_edo_sequence</code>s from [[#My Python 3 code]]): | ||
* [[User:Godtone/optimal edo sequences]] | * [[User:Godtone/optimal edo sequences]] (and [[User:Godtone/strict_optimal_edo_sequences]]) | ||
...as well as by my own knowledge of tuning theory. | ...as well as by my own knowledge of tuning theory. | ||
| Line 374: | Line 374: | ||
* I gave names for the interval prefixes and interval name abbreviations for [[5L 7s]] (p-chromatic) and [[7L 5s]] (m-chromatic). For [[7L 5s]] I picked "chrome" as it is strongly befitting of meantone as meantone does the 7-limit efficiently, elegantly and colourfully, and because its a contraction of "chromatic" and the "me" in "meantone". Pronounced like the word. For [[5L 7s]], in contrast with [[5L 7s]] which is mellow and harmonic, [[5L 7s]] is sharp and active, perhaps like fire, hence I picked "pyr-" from "pyro" and from "[py]thago[r]ean", with the letters "pyr" of course also being for "[p]a[r]a[py]th", "su[p]e[rpy]th" and "ult[r]a[py]yth". | * I gave names for the interval prefixes and interval name abbreviations for [[5L 7s]] (p-chromatic) and [[7L 5s]] (m-chromatic). For [[7L 5s]] I picked "chrome" as it is strongly befitting of meantone as meantone does the 7-limit efficiently, elegantly and colourfully, and because its a contraction of "chromatic" and the "me" in "meantone". Pronounced like the word. For [[5L 7s]], in contrast with [[5L 7s]] which is mellow and harmonic, [[5L 7s]] is sharp and active, perhaps like fire, hence I picked "pyr-" from "pyro" and from "[py]thago[r]ean", with the letters "pyr" of course also being for "[p]a[r]a[py]th", "su[p]e[rpy]th" and "ult[r]a[py]yth". | ||
* Similarly to how I made an exception for the 1Lns scale form of [[1L 6s]], I'm also making an exception to include the multiMOSS of [[6L 2s]] as [[ | * Similarly to how I made an exception for the 1Lns scale form of [[1L 6s]], I'm also making an exception to include the multiMOSS of [[6L 2s]] as [[echidna]] (from which the MOSS derives its name) is a strong and important temperament to me with a period of half an octave and where one generator is both 11/10 and 9/7 depending on from which direction you view it, as 11/10 * 9/7 is extremely close to half an octave, the period for this MOSS scale. ("MultiMOSS" stands for "multi-period Moment Of Symmetry Scale".) '''However,''' this would not be included if I were to have this as "the semi-official [[TAMNAMS]] minimal MOSS name list", because this is a true exception to a lot of the design principles behind choosing this set of MOSSes to name and recognise as important. | ||
{| class="wikitable center-all" | {| class="wikitable center-all" | ||
| Line 466: | Line 466: | ||
== My Python 3 code == | == My Python 3 code == | ||
IMPORTANT NOTE: there seems to be | IMPORTANT NOTE: there seems to be bugs for subgroup mappings at the moment, pending investigation, but ideally usage of subgroups should be made far easier too: | ||
<syntaxhighlight lang="python"> | <syntaxhighlight lang="python"> | ||
>>> sg = [2, 3, 7, 11, 13, 17, 19] | >>> sg = [2, 3, 7, 11, 13, 17, 19] | ||
| Line 1,518: | Line 1,518: | ||
return result | return result | ||
# the length of the mediant path of whichever octave-revoicing gives the interval x the least length | |||
def mediant_complexity(x,revoicing_octs=7): | def mediant_complexity(x,revoicing_octs=7): | ||
mincomplexity = 2**30 | mincomplexity = 2**30 | ||
| Line 1,550: | Line 1,551: | ||
print() | print() | ||
return spaces | return spaces | ||
# there is only finitely many EDOs which provide some simplification of a set of intervals as contrasted to all-distinct | |||
def efficient_edos( ivs, inconsistencies=0, min_simplifications=1, edos=range(1,1000) ): | |||
if type(ivs)==int: | |||
ivs = odd_lim(ivs) | |||
elif type(ivs)==list and type(ivs[0])==int: | |||
ivs = odd_lim(1,[],ivs) | |||
results = [] | |||
for edo in edos: | |||
v = edo | |||
if type(v)==int: | |||
v = val( lim(max([ prime_idx(len(fact(x))-1) for x in ivs ])), ed(edo) ) | |||
# else v is assumed to be a mapping | |||
m = dict() | |||
for x in ivs: # collect mappings of intervals | |||
sedo = map_iv(v,x) | |||
if sedo in m: | |||
m[sedo].append(x) | |||
else: | |||
m[sedo] = [x] | |||
if len(inconsistent_ivs_by_val(ivs,v)) <= inconsistencies: | |||
if len(ivs) - len([ sedo for sedo in m ]) >= min_simplifications: | |||
results.append(edo) | |||
return results | |||
# the following definitions are equivalent in the set of commas considered 7-limit dieses: | |||
# dieses(4,odd_lim(9),odd_lim(9)) == dieses(4,odd_lim(9),odd_lim(7)) == dieses(5,odd_lim(9),odd_lim(7)) | |||
def dieses( max_n=4, gs=odd_lim(9), targets=None, show=False, minerr=steps(20000/19683,1)/4 ): | |||
if not targets: | |||
targets = gs | |||
dieses_found = dict() | |||
for g in gs: | |||
for target in targets+[(2,1)]: | |||
for n in range(2,max_n+1): | |||
candidate = reduce(div_iv( target, mul_iv(*[g]*n) )) | |||
if steps(candidate,1)>1/2: | |||
candidate = div_iv((2,1),(candidate)) | |||
if steps(candidate,1)/n >= steps(20000/19683,1)/4 and steps(250/243,1) >= steps(candidate,1): | |||
if candidate not in dieses_found: | |||
dieses_found[candidate] = [] | |||
dieses_found[candidate].append(( n, g, target, steps(candidate,ed(1200))/n )) | |||
if show: | |||
for diesis in dieses_found: | |||
mindamage = min([ dieses_found[diesis][k][3] for k in range(len( dieses_found[diesis] )) ]) | |||
if mindamage >= minerr: | |||
def equiv(d): | |||
return ', '.join([ '('+striv(eq[1])+')^'+str(eq[0])+' ~ '+striv(eq[2])+' (~'+ | |||
str( int(eq[3]*100+.5)/100 )[:5]+'c)' for eq in dieses_found[d] ]) | |||
print( | |||
pad( striv(diesis), 12 ), | |||
pad( str( int(mindamage*100+.5)/100 )[:6]+'c', 7, '.' ), | |||
equiv(diesis) | |||
) | |||
results = [diesis for diesis in dieses_found] | |||
results.sort(key=lambda x: as_float(x)) | |||
return results | |||
</syntaxhighlight> | </syntaxhighlight> | ||
| Line 1,622: | Line 1,679: | ||
'''It should be compatible with any Launchpad that has [[#Putting the Launchpad in programmer mode|programmer mode]]; it has been confirmed to work for the Launchpad X so will likely also work for a Launchpad Mini MK3.''' | '''It should be compatible with any Launchpad that has [[#Putting the Launchpad in programmer mode|programmer mode]]; it has been confirmed to work for the Launchpad X so will likely also work for a Launchpad Mini MK3.''' | ||
ALSO: This should go without saying but take care of your launchpad! If you wipe it don't expect it to be properly responsive until fully dry and even then wiping it can have risks if the liquid goes inside. Similarly, do not bang it and probably don't leave it upside down (especially if for long periods of time) in case it causes the velocity sensitivity to go weird. Treat it as an instrument. If you do all this, it should be fine to use it for its intended purpose: just don't press ''too'' hard; try not press with more velocity than the buttons actually require, if possible. (Because of my silliness (not heeding such obvious procedures) there is a possibility that I may have weared my launchpad slightly in that I think I now require more pressure for the pressure-sensitive pads. I thought it responsible to add this note about taking care of your launchpad, as we are technically using it in a nonstandard way by treating the buttons as though they were just insensitive pads that require extra velocity/pressure.) | ALSO: This should go without saying but take care of your launchpad! If you wipe it don't expect it to be properly responsive until fully dry and even then wiping it can have risks if the liquid goes inside. Similarly, do not bang it and probably don't leave it upside down (especially if for long periods of time) in case it causes the velocity sensitivity to go weird. Treat it as an instrument. If you do all this, it should be fine to use it for its intended purpose: just don't press ''too'' hard; try not press with more velocity than the buttons actually require, if possible. (Because of my silliness (not heeding such obvious procedures) there is a possibility that I may have weared my launchpad slightly in that I think I now require more pressure for the pressure-sensitive pads. I thought it responsible to add this note about taking care of your launchpad, as we are technically using it in a nonstandard way by treating the buttons as though they were just insensitive pads that require extra velocity/pressure.) | ||
| Line 1,631: | Line 1,686: | ||
=== Installation issues/troubleshooting strategies/recommendations === | === Installation issues/troubleshooting strategies/recommendations === | ||
The most potentially difficult part is that depending on what OS you are using, how you have Python installed, what version, etc. there can be complications so that running <code>pip install rtmidi</code> and <code>pip install mido</code> in a terminal does not work, or only appears to work so that there's issues when the code tries to use mido. I list potential issues below, so please read carefully for something applicable to your case if it isn't going smoothly. | The most potentially difficult part is that depending on what OS you are using, how you have Python installed, what version, etc. there can be complications so that running <code>pip install rtmidi</code> and <code>pip install mido</code> in a terminal does not work, or only appears to work so that there's issues when the code tries to use mido. I list potential issues below, so please read carefully for something applicable to your case if it isn't going smoothly. | ||
'''UPDATE (2026-10):''' I have found that latest version of Python might not work; if this is the case, use a version of Python 3.13. | |||
'''IMPORTANT: A strange error has been found: Python 3.14 and later versions have removed a functionality used by mido internally, so downgrading to Python 3.12 is required if nothing here works.''' | |||
'''IMPORTANT:''' Before deeming an installation of mido/rtmidi to "not be working", make sure that the issue is not just one of what MIDI ports are being autoselected; see (6.) onwards for details. | '''IMPORTANT:''' Before deeming an installation of mido/rtmidi to "not be working", make sure that the issue is not just one of what MIDI ports are being autoselected; see (6.) onwards for details. | ||