Godtone
Joined 17 December 2020
new section linking subpages |
m →My Python 3 code: clarification |
||
| (10 intermediate revisions by the same user not shown) | |||
| Line 105: | Line 105: | ||
* 31: The next EDO that melodically approximates the 11-limit, and considerably better. Extremely nice arrangement of intervals that feels weirdly intuitive and ideal. Colourful EDO. Basically ideal meantone tuning as more notes than this is overkill for meantone if you don't specifically want meantone. | * 31: The next EDO that melodically approximates the 11-limit, and considerably better. Extremely nice arrangement of intervals that feels weirdly intuitive and ideal. Colourful EDO. Basically ideal meantone tuning as more notes than this is overkill for meantone if you don't specifically want meantone. | ||
* 32: 16 EDO with a sharp fifth. I like it primarily because of it being a power of 2. Exploration into this EDO could be interesting. 80 EDO offers a reasonably good approximation of it through a 16L16s MOSS. | * 32: 16 EDO with a sharp fifth. I like it primarily because of it being a power of 2. Exploration into this EDO could be interesting. 80 EDO offers a reasonably good approximation of it through a 16L16s MOSS. | ||
* 34: The first good approximation of the 5-prime-limit due to being the first reasonably accurate tuning of [[Kleismic family|kleismic]] and [[srutal archagall]] which are IMO the best 5-limit temperaments that observe the [[81/80|syntonic comma]]. 19 is also a tuning for kleismic but feels like it doesn't do justice to the accuracy and pristineness of kleismic to me, plus its harmonic interpretation is pretty lacking. And 22 is very obviously | * 34: The first good approximation of the 5-prime-limit due to being the first reasonably accurate tuning of [[Kleismic family|kleismic]] and [[srutal archagall]] which are IMO the best 5-limit temperaments that observe the [[81/80|syntonic comma]]. 19 is also a tuning for kleismic but feels like it doesn't do justice to the accuracy and pristineness of kleismic to me, plus its harmonic interpretation is pretty lacking. And 22 is very obviously too high-damage for srutal archagall. Has the sharp 3/2's of 17 EDO, and as 17 EDO is a good colour system, 34 EDO is a natural extension. Also is a very logical "completion" of 17 due to giving a very logical 2.3.5.13.17(.23)-subgroup interpretation of the sqrt(2).sqrt(3) subgroup with some really intriguing possibilities. If you're lacking in inspiration and its wide array of supported MOSSes aren't inspiration enough, try taking a look at the diaschismic-tetracot continuum ([[2048/2025]])<sup>n</sup> / ([[20000/19683]]). | ||
* 35: A subset of 140 EDO, a ridiculously strong generalist system, which endows it with magical tuning qualities. | * 35: A subset of 140 EDO, a ridiculously strong generalist system, which endows it with magical tuning qualities. | ||
* 36: Because of being a superset of 12, quite overlooked. It is actually a very good subgroup temperament! A natural extension of 12 EDO's colour palette, preferring to avoid the neutral and semi- intervals of 24 EDO. I should note though that while both 24 and 36 are reasonably good systems, I do not think they should be used together, as there are preferable EDOs in the high end range, such as 80 EDO. | * 36: Because of being a superset of 12, quite overlooked. It is actually a very good subgroup temperament! A natural extension of 12 EDO's colour palette, preferring to avoid the neutral and semi- intervals of 24 EDO. I should note though that while both 24 and 36 are reasonably good systems, I do not think they should be used together, as there are preferable EDOs in the high end range, such as 80 EDO. | ||
| 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,346: | Line 1,346: | ||
# and not underweighting simpler intervals and accounting for that more complex intervals will tend to be used | # and not underweighting simpler intervals and accounting for that more complex intervals will tend to be used | ||
# in a harmonic/chordal context which justifies their otherwise-higher effective felt error through templating | # in a harmonic/chordal context which justifies their otherwise-higher effective felt error through templating | ||
if weighting== | if type(weighting)==str: | ||
weighting = | if weighting in [None,'none','unweighted','trivial','basic','constant']: | ||
weighting = 0 | |||
elif weighting in ['','default','proportional']: | |||
weighting = 1 | |||
weighting = lambda x: iv_complexity(x)** | elif weighting in ['sensitive','dyadic']: | ||
weighting = 2 | |||
elif weighting=='simple': | |||
weighting = -0.5 # as we may square after when doing a MSE, we use the square root | |||
if type(weighting) in [int,float]: | |||
weighting = lambda x,w=weighting: iv_complexity(x)**w | |||
global ivs_cache | global ivs_cache | ||
global ivs_int_cache | global ivs_int_cache | ||
| Line 1,450: | Line 1,455: | ||
def strict_optimal_edo_sequence(ivs,edo_set=range(2,311+1),weighting=lambda x: iv_complexity(x),combine='avg',mapping=True): | def strict_optimal_edo_sequence(ivs,edo_set=range(2,311+1),weighting=lambda x: iv_complexity(x),combine='avg',mapping=True): | ||
return optimal_edo_sequence(lambda edo: et_badness(ivs,edo,lambda rel_err: rel_err**2,weighting,combine,mapping),edo_set) | return optimal_edo_sequence(lambda edo: et_badness(ivs,edo,lambda rel_err: rel_err**2,weighting,combine,mapping),edo_set) | ||
# returns a set of odds in the subgroup that are sorted by their octave-reduced size | |||
# which map to every distinct number of steps/degrees of the val given, therefore, | |||
# dwarf(lim(p),N) is the set of odds for the dwarf scale of N EDO in the p-limit | |||
def dwarf(sg,v): | |||
if type(v)==int: # to be able to specify N for the patent val for N EDO | |||
v = val( lim(max(sg)), ed(v) ) | |||
result = [0] * v[0] # implies you can have a tritave dwarf if sg and v agree on the subgroup | |||
odd = 1 | |||
while 0 in result: | |||
if in_subgroup(odd,sg) and result[ map_iv(v,(odd,1)) % v[0] ]==0: | |||
result[ map_iv(v,(odd,1)) % v[0] ] = odd | |||
odd += 2 | |||
return result | |||
def scalestr(liststr): | def scalestr(liststr): | ||
| Line 1,499: | 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,505: | Line 1,525: | ||
mincomplexity = min(mincomplexity,len(mediant_path( mul_iv(x,(2**octs,1)) ))) | mincomplexity = min(mincomplexity,len(mediant_path( mul_iv(x,(2**octs,1)) ))) | ||
return mincomplexity | return mincomplexity | ||
# showmode: minimum number of equated interval pairs (incl. distinct octave-complements). | |||
# if minimum isnt reached, only the spacing interval is shown. 0 means dont print anything. | |||
# for odd-limits, to look for "multiple indistinction commas", use 3 for showmode. | |||
def spaces_in_set(ivs,max_cents = 100,showmode = 1): | |||
spaces = dict() | |||
if type(max_cents) in [tuple,float,int]: | |||
max_cents = steps(max_cents,ed(1200)) | |||
for lower in ivs: | |||
for upper in ivs: | |||
diff = div_iv(upper,lower) | |||
if 0 < steps(diff,ed(1200)) <= max_cents: | |||
if diff not in spaces: | |||
spaces[diff] = [(upper,lower)] | |||
else: | |||
spaces[diff].append((upper,lower)) | |||
commas = [comma for comma in spaces] | |||
commas.sort(key=lambda x: steps(x,1)) | |||
if showmode: | |||
for comma in commas: | |||
print(striv(comma)+':',', '.join([ | |||
'('+striv(ivpair[0])+')/('+striv(ivpair[1])+')' for ivpair in spaces[comma] | |||
if len(spaces[comma])>=showmode | |||
])) | |||
print() | |||
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( n, inconsistencies=0, min_simplifications=1, edos=range(1,1000) ): | |||
if type(n)==int: | |||
n = odd_lim(n) | |||
elif type(n)==list and type(n[0])==int: | |||
n = odd_lim(1,[],n) | |||
results = [] | |||
for edo in edos: | |||
v = edo | |||
if type(v)==int: | |||
v = val( lim(max([ prime_idx(len(fact(x))-1) for x in n ])), ed(edo) ) | |||
# else v is assumed to be a mapping | |||
m = dict() | |||
for x in n: # 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(n,v)) <= inconsistencies: | |||
if len(n) - len([ sedo for sedo in m ]) >= min_simplifications: | |||
results.append(edo) | |||
return results | |||
</syntaxhighlight> | </syntaxhighlight> | ||
| Line 1,584: | Line 1,654: | ||
=== 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. | ||
'''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. | ||