-
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Replace tune2, tune3 and tune4 with a single search over integer mult…
…iples
- Loading branch information
Showing
9 changed files
with
188 additions
and
185 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -267,11 +267,10 @@ const S = @2.7.11 | |
### errorTE | ||
In order to compare the quality of vals w.r.t. just intonation SonicWeave provides the `errorTE` helper that measures [RMS TE error](https://en.xen.wiki/w/Tenney-Euclidean_temperament_measures#TE_error) in cents. Providing explicit subgroups is highly recommended so that irrelevant higher primes do not interfere with the measure. | ||
|
||
### tune2 | ||
The helper `tune2` takes two vals and tries to find a combination that's closer to just intonation, effectively performing constrained Tenney-Euclidean optimization (CTE). E.g. `tune2([email protected], [email protected])` finds 31p. Given more iterations `tune2([email protected], [email protected], 7)` finds an equal temperament in the thousands that's virtually indistinguishable from the true meantone CTE tuning. | ||
### tune | ||
The helper `tune` takes an array of vals and tries to find a combination that's closer to just intonation, effectively performing constrained Tenney-Euclidean optimization (CTE). E.g. `tune([[email protected], [email protected]])` finds 31p. Given a large search radius `tune2([email protected], [email protected], 200)` finds an equal temperament in the thousands that's virtually indistinguishable from the true meantone CTE tuning. | ||
|
||
### tune3 and tune4 | ||
The helpers `tune3` and `tune4` do the same but try combinations of 3 or 4 vals instead. Assuming the vals are linearly independent the process corresponds to rank-3 and rank-4 CTE optimization. | ||
With more than two linearly independent vals the process corresponds to higher rank CTE optimization. | ||
|
||
### Discovering vals | ||
Every just intonation subgroup has a generalized patent val sequence that dances around approximations to the just intonation point i.e. the perfectly pure tuning. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2703,4 +2703,41 @@ describe('SonicWeave expression evaluator', () => { | |
); | ||
expect(fraction).toBe('11/9'); | ||
}); | ||
|
||
it('can combine two vals to approach the JIP', () => { | ||
const thirtyOne = evaluate('tune([[email protected], [email protected]])') as Val; | ||
expect(thirtyOne.value.toIntegerMonzo()).toEqual([31, 49, 72]); | ||
}); | ||
|
||
it('can combine two vals to approach the JIP (Wilson metric)', () => { | ||
const eighty = evaluate( | ||
'tune([[email protected], [email protected]], 5, [1 % 2, 3 /_ 2 % 3, 5 /_ 2 % 5])' | ||
) as Val; | ||
expect(eighty.value.toIntegerMonzo()).toEqual([126, 200, 293]); | ||
}); | ||
|
||
it('can combine three vals to approach the JIP', () => { | ||
const fourtyOne = evaluate('tune([[email protected], [email protected], [email protected]])') as Val; | ||
expect(fourtyOne.value.toIntegerMonzo()).toEqual([41, 65, 95, 115]); | ||
}); | ||
|
||
it('can combine four vals to approach the JIP', () => { | ||
const val = evaluate('tune([[email protected], [email protected], [email protected], [email protected]])') as Val; | ||
expect(val.value.toIntegerMonzo()).toEqual([72, 114, 167, 202, 249]); | ||
}); | ||
|
||
it("doesn't move from 31p when tuned with 5p", () => { | ||
const p31 = evaluate('str(tune([[email protected], [email protected]]))'); | ||
expect(p31).toBe('<31 49 72]'); | ||
}); | ||
|
||
it('moves from 31p when tuned with 5p if given a large enough radius', () => { | ||
const p31 = evaluateExpression('str(tune([[email protected], [email protected]], 6))'); | ||
expect(p31).toBe('<191 302 444]'); | ||
}); | ||
|
||
it('tunes close to CTE meantone if given a large enough radius', () => { | ||
const cents = evaluate('str(cents(3/2 tmpr tune([[email protected], [email protected]], 200), 4))'); | ||
expect(cents).toEqual('697.2143'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,7 @@ import { | |
getSourceVisitor, | ||
parseAST, | ||
} from '../../parser'; | ||
import {Interval, Val} from '../../interval'; | ||
import {Interval} from '../../interval'; | ||
import {builtinNode, track} from '../../stdlib'; | ||
import {Fraction} from 'xen-dev-utils'; | ||
|
||
|
@@ -366,30 +366,6 @@ describe('SonicWeave standard library', () => { | |
); | ||
}); | ||
|
||
it('can combine two vals to approach the JIP', () => { | ||
const thirtyOne = evaluateExpression('tune2([email protected], [email protected])') as Val; | ||
expect(thirtyOne.value.toIntegerMonzo()).toEqual([31, 49, 72]); | ||
}); | ||
|
||
it('can combine two vals to approach the JIP (Wilson metric)', () => { | ||
const eighty = evaluateExpression( | ||
'tune2([email protected], [email protected], 2, [log(2)/2, log(3)/3, log(5)/5])' | ||
) as Val; | ||
expect(eighty.value.toIntegerMonzo()).toEqual([126, 200, 293]); | ||
}); | ||
|
||
it('can combine three vals to approach the JIP', () => { | ||
const fourtyOne = evaluateExpression('tune3([email protected], [email protected], [email protected])') as Val; | ||
expect(fourtyOne.value.toIntegerMonzo()).toEqual([41, 65, 95, 115]); | ||
}); | ||
|
||
it('can combine four vals to approach the JIP', () => { | ||
const val = evaluateExpression( | ||
'tune4([email protected], [email protected], [email protected], [email protected])' | ||
) as Val; | ||
expect(val.value.toIntegerMonzo()).toEqual([94, 149, 218, 264, 325]); | ||
}); | ||
|
||
// Remember that unison (0.0 c) is implicit in SonicWeave | ||
|
||
it('has harmonic segments sounding downwards', () => { | ||
|
@@ -1705,19 +1681,4 @@ describe('SonicWeave standard library', () => { | |
'[[email protected], [email protected], [email protected], [email protected], [email protected]]' | ||
); | ||
}); | ||
|
||
it("doesn't move from 31p when tuned with 5p", () => { | ||
const p31 = evaluateExpression('str(tune2([email protected], [email protected]))'); | ||
expect(p31).toBe('<31 49 72]'); | ||
}); | ||
|
||
it('moves from 31p when tuned with 5p if given enough time', () => { | ||
const p31 = evaluateExpression('str(tune2([email protected], [email protected], 3))'); | ||
expect(p31).toBe('<191 302 444]'); | ||
}); | ||
|
||
it('tunes close to CTE meantone if given enough time', () => { | ||
const scale = expand('cents(3/2 tmpr tune2([email protected], [email protected], 7), 4)'); | ||
expect(scale).toEqual(['697.2143']); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.