Ejemplo n.º 1
0
    def test_others(self):
        for test_file in OTHERS:
            with open(test_file, 'r') as fh:
                o = jxon.load(fh)

            self.assertTrue(jxon.jxon_equal(o, jxon.loads(jxon.dumps(o))))
            self.assertTrue(
                jxon.jxon_equal(o, jxon.loads(jxon.dumps(o, indent=2))))
Ejemplo n.º 2
0
    def test_idempotence(self):
        for test_file in ALL_TESTS:
            fullpath = 'tests/' + test_file
            with open(fullpath, 'r') as fh:
                o = jxon.load(fh)

            self.assertTrue(jxon.jxon_equal(o, jxon.loads(jxon.dumps(o))))
            self.assertTrue(
                jxon.jxon_equal(o, jxon.loads(jxon.dumps(o, indent=2))))
Ejemplo n.º 3
0
from functools import cache
import jxon
from src.ji import Interval, JI

MAJOR_EDOS = (5, 7, 12, 15, 17, 19, 22, 24, 31)

MAJOR_MINOR_INTERVALS = ["2", "3", "6", "7"]
PERFECT_INTERVALS = ["4", "5"]

with open("static/consonance/consonances.jxon", "r") as fh:
    CONSONANCES = jxon.load(fh)

with open("static/consonance/dissonances.jxon", "r") as fh:
    DISSONANCES = jxon.load(fh)


class EDOInterval(Interval):
    __instances = {}

    def __new__(cls, steps, edo_steps):
        t = (steps, edo_steps)
        if t not in cls.__instances:
            cls.__instances[t] = super(EDOInterval, cls).__new__(cls)

        return cls.__instances[t]

    def __init__(self, steps: int, edo_steps: int):
        self.steps = steps
        self.edo_steps = edo_steps

    def octaves(self):
Ejemplo n.º 4
0
import math
import jxon


with open("static/ji/intervals.jxon", "r") as fh:
    NAMED_INTERVALS = jxon.load(fh)


class Interval:
    def octaves(self) -> float:
        raise NotImplementedError

    def cents(self):
        return round(self.octaves() * 1200, 1)

    def __gt__(self, other):
        return self.cents() > other.cents()
        
    def __lt__(self, other):
        return self.cents() < other.cents()


class JI(Interval):
    def __init__(self, denom, num):
        assert num >= denom
        self.num = num
        self.denom = denom
        self.ratio = (denom, num)

    def octaves(self):
        return math.log2(self.num / self.denom)
Ejemplo n.º 5
0
    def edo(self):
        return EDO(self.edo_steps())

    def size(self):
        return len(self.jumps)


SCALES_DIR = "static/scales"
NAMED_CYCLES = {}
for filename in os.listdir(SCALES_DIR):
    if filename == "scales.jxsd":
        continue

    assert (re.fullmatch(r"[0-9]+edo\.jxon", filename))
    with open(os.path.join(SCALES_DIR, filename), "r") as fh:
        cycles = jxon.load(fh)
        # uniqueness constraint - will hopefully enforce in jxon at some point
        assert len(set(map(lambda c: c["name"], cycles))) == len(cycles)
        NAMED_CYCLES[int(filename[:-8])] = cycles


class CycleMetaclass(type):
    __instances = {}

    def __call__(cls, jumps):
        modes = [
            Mode(jumps[i:] + jumps[:i])
            for i in range(len(jumps))
        ]

        canon_mode = min(modes, key=lambda mode: mode.weight())
Ejemplo n.º 6
0
from .just_interval import JI
from functools import cache

ORDINALS = [
    "0th",
    "1st",
    "2nd",
    "3rd",
    "4th",
    "5th",
    "6th",
    "7th",
]

with open("static/ji/chords.jxon", "r") as fh:
    NAMED_CHORDS = jxon.load(fh)

with open("static/ji/intervals.jxon", "r") as fh:
    for ivl in jxon.load(fh):
        NAMED_CHORDS.append({
            "name": ivl["name"],
            "ratio": [ivl["denom"], ivl["num"]]
        })


class JustChord:
    def __init__(self, ratio: [int]):
        if not all(ratio[i] < ratio[i + 1] for i in range(len(ratio) - 1)):
            raise ValueError(f"JustChord ratio must be increasing: {ratio}")
        self.ratio = tuple(ratio)