def mk_loop_cadence(loopsize: int, meter: metre.Metre) -> old.JICadence: size = meter.size loop_amount = size // loopsize rest = size % loopsize harmony = ji.JIHarmony([ji.r(3, 2)]) cadence = [old.Chord(harmony, loopsize) for i in range(loop_amount)] if rest: cadence.append(old.Chord(harmony, rest)) return old.JICadence(cadence)
def mk_simple_conversion( mode: modes.Mode, funcs: tuple, subfunctions_per_interpol: tuple ) -> old.JICadence: """Expect real functions (with applied modulation), not symbolic functions""" def get_from_func_pitch(func) -> ji.JIPitch: p = func(mode) if p.set_val_border(2).primes == (3,): # 3 * 9 doesn't exist in current tuning return p.normalize(2) - ji.r(2, 1) else: return mel.TheEmptyPitch def filter_subfunc_pitch(pitch) -> ji.JIPitch: if pitch == ji.r(1, 1): pitch += ji.r(2, 1) if pitch in SITER_BARUNG.pitches: return pitch else: return mel.TheEmptyPitch res = [] for func0, func1, subfuncline in zip(funcs, funcs[1:], subfunctions_per_interpol): fp = get_from_func_pitch(func0) subfunc_pitches = list( (filter_subfunc_pitch(p),) for p in subfuncline.convert_signifiers2pitches(mode, func0, func1)[:-1] ) if fp: subfunc_pitches[0] = subfunc_pitches[0] + (fp,) for h in subfunc_pitches: h = tuple(p for p in h if p) res.append(h) return old.JICadence([old.Chord(ji.JIHarmony(h), 1) for h in res])
def mk_simple_conversion(mode: modes.Mode, compounds_per_function: tuple, funcs: tuple) -> old.JICadence: def define_gong(mode) -> ji.JIPitch: gong_pitch = ji.r( functools.reduce(operator.mul, (mode.x, mode.y, mode.z)), 1) if not mode.gender: gong_pitch = gong_pitch.inverse() return gong_pitch.normalize(2) - ji.r(4, 1) def get_pitch(f) -> ji.JIPitch: p = f(mode) if p.set_val_border(2).primes == ( 3, ): # 3 * 9 doesn't exist in current tuning return mel.TheEmptyPitch else: return f(mode).normalize() - ji.r(2, 1) gong = define_gong(mode) pitches = tuple(get_pitch(f) for f in funcs) pitches = ((gong, p) if f.gong else (p, ) for f, p in zip(funcs, pitches)) return old.JICadence([ old.Chord(ji.JIHarmony(tuple(pi for pi in p if pi)), delay) for p, delay in zip(pitches, compounds_per_function) ])
def mk_siter_cadence( self, siter_panerus_pitch, gender, previous_signified: int, previous_side_prime: int, current_signified: int, current_side_prime: int, following_signified: int, following_side_prime: int, stresses, ) -> old.JICadence: siter_pitches = self.siter_style.convert2interpolation( gender, previous_signified, previous_side_prime, current_signified, current_side_prime, following_signified, following_side_prime, stresses, ) siter_pitches = tuple(ji.JIHarmony([p]) for p in siter_pitches) siter_pitches = (ji.JIHarmony(siter_panerus_pitch), ) + siter_pitches return old.JICadence([old.Chord(h, 1) for h in siter_pitches])
def create_cadence( self, stresses: tuple, does_siter_play: tuple, gender: bool, previous_signified: int, current_signified: int, following_signified: int, previous_side_prime: int, current_side_prime: int, following_side_prime: int, ) -> old.JICadence: chord0 = old.Chord(ji.JIHarmony([]), 1) pattern = self.detect_pattern( stresses, does_siter_play, gender, previous_signified, current_signified, following_signified, previous_side_prime, current_side_prime, following_side_prime, ) final_cadence = [chord0] for idx, pat in enumerate(pattern): pat = list(pat) final_cadence += pat return old.JICadence(final_cadence)
def mk_cadence(self, scale_functions: str, rhythm: str) -> old.Cadence: def make_pitches(scale_functions) -> mel.Cadence: return sw.translate_from_file(scale_functions, self.__decodex) def make_rhythms(rhythm) -> tuple: typr = type(rhythm) if typr == int or typr == float: return tuple(rhythm for i in range(len(harmonies))) elif typr == str: with open(rhythm, "r") as r: lines = tuple(l for l in r.read().splitlines() if l) rhythm = " ".join(tuple(l for l in lines if l[0] != "#")) rhythm = rhythm.split(" ") rhythm = tuple(float(n) for n in rhythm if n) return rhythm elif typr == tuple: assert len(rhythm) == len(harmonies) return rhythm else: msg = "Unknown TYPE '{0}' for argument rhythm.".format(typr) raise ValueError(msg) harmonies = make_pitches(scale_functions) rhythms = make_rhythms(rhythm) return old.Cadence(old.Chord(h, r) for h, r in zip(harmonies, rhythms))
def mk_loop_cadence_with_tuk(loopsize: int, meter: metre.Metre) -> old.JICadence: size = meter.size loop_amount = size // loopsize rest = size % loopsize harmony0 = ji.JIHarmony([ji.r(3, 2)]) harmony1 = ji.JIHarmony([ji.r(1, 1)]) basic_cadence = [old.Chord(harmony0, 0.5) ] + [old.Chord(harmony1, 1) for i in range(loopsize - 1)] basic_cadence.append(old.Chord(harmony1, 0.5)) print(old.JICadence(basic_cadence).duration) cadence = [basic_cadence for i in range(loop_amount)] cadence = functools.reduce(operator.add, cadence) if rest: cadence.append(old.Chord(harmony0, rest)) return old.JICadence(cadence)
def convert2cadence(self, tempo_factors_per_unit: tuple, delays: tuple) -> old.JICadence: """ """ def return_item_and_sizes(element, lv=0) -> tuple: if type(element) == ji.JIHarmony or element == mel.TheEmptyPitch: return ((element, lv), ) else: ret = tuple([]) for tup in (return_item_and_sizes(it, lv + 1) for it in element): ret += tup return ret divisions_per_elements = int(tempo.TempoLine.divisions_per_element) cadence = [] unit_count = 0 for meter in self.__structure: for compound in meter: for unit in compound: delay = delays[unit_count] if delay: if cadence: cadence[-1].delay += delay.duration cadence[-1].duration += delay.duration else: cadence.append(old.Rest(delay.duration)) factors = tempo_factors_per_unit[unit_count] abstract_delays = [] harmonies = [] for element in unit: item_and_size_pairs = return_item_and_sizes(element) for pair in item_and_size_pairs: harmonies.append(pair[0]) de = int(divisions_per_elements * (1 / (2**pair[1]))) abstract_delays.append(de) real_delays = tuple( itertools.accumulate([0] + abstract_delays)) real_delays = tuple( sum(factors[idx0:idx1]) for idx0, idx1 in zip(real_delays, real_delays[1:])) for h, de in zip(harmonies, real_delays): if h: cadence.append(old.Chord(h, de)) else: cadence.append(old.Rest(de)) unit_count += 1 cadence = old.JICadence(cadence).discard_rests() return cadence
def load_cadence(name: str, pitch=None, rhythm=None): if not pitch: pitch = sw.translate_from_file("pitch/{0}".format(name)) if not rhythm: with open("rhythm/{0}".format(name), "r") as rhythm: rhythm = " ".join(rhythm.read().splitlines()) rhythm = rhythm.split(" ") rhythm = tuple(float(n) for n in rhythm if n) return old.JICadence([old.Chord(p, r) for p, r in zip(pitch, rhythm)])
def mk_mdc_gong_and_tong(cadence, timeflow) -> tuple: cadence_gong, cadence_tong = [], [] for chord in cadence: hg, ht = [], [] for p in chord.pitch: if p < ji.r(1, 2): hg.append(p) else: ht.append(p) cadence_gong.append(old.Chord(ji.JIHarmony(hg), chord.delay)) cadence_tong.append(old.Chord(ji.JIHarmony(ht), chord.delay)) cadences = tuple( old.JICadence(c).discard_rests() for c in (cadence_gong, cadence_tong)) return tuple( MDC.mk_mdc_by_cadence(c, timeflow, Score.TIME_LV_PER_INSTRUMENT[0], False) for c in cadences)
def __call__(self, gender: bool, main_prime: int, side_prime: int) -> old.JICadence: pitches = sw.translate( self.__line, decodex={ self.main: str(main_prime), self.side: str(side_prime) }, inverse=not gender, ) return old.JICadence( [old.Chord(h, r) for h, r in zip(pitches, self.__rhythms)])
def __call__(self, gender: bool, main_prime: int, side_prime: int) -> old.JICadence: if not main_prime: main_prime = 3 if not side_prime: side_prime = 5 not_current_main_primes = tuple(p for p in (3, 5, 7) if p != main_prime) if len(not_current_main_primes) == 3: not_current_main_primes = (5, 7) if not_current_main_primes[0] == side_prime: not_current_main_primes = tuple(reversed(not_current_main_primes)) not_current_side_primes = tuple(p for p in (3, 5, 7) if p != side_prime) if len(not_current_side_primes) == 3: not_current_side_primes = (5, 7) if not_current_side_primes[0] == main_prime: not_current_side_primes = tuple(reversed(not_current_side_primes)) if main_prime == 9: tranformed_mp = 3 else: tranformed_mp = main_prime if side_prime == 9: tranformed_sp = 3 else: tranformed_sp = side_prime pitches = sw.translate( self.line, decodex={ self.main: str(main_prime), self.side: str(side_prime), self.not_current_main_prime0: str(not_current_main_primes[0]), self.not_current_main_prime1: str(not_current_main_primes[1]), self.not_current_side_prime0: str(not_current_side_primes[0]), self.not_current_side_prime1: str(not_current_side_primes[1]), self.transformed_main_prime: str(tranformed_mp), self.transformed_side_prime: str(tranformed_sp), }, inverse=not gender, ) return old.JICadence( [old.Chord(h, r) for h, r in zip(pitches, self.rhythms)])
def test_make_cadence(self): p_lines = ("# simple melody", "6 5 3 2", "(1 5) 2 3 2") pitch_name = "pitches" scl_lines = ( "Imaginary perfect slendro", "5", "240.", "480.", "720.", "960.", "1200.", ) scale_name = "slendro.scl" names = (pitch_name, scale_name) for name, lines in zip(names, (p_lines, scl_lines)): with open(name, "w") as scl: scl.write("\n".join(lines)) concert_pitch = 260 scale = mel.Mel.from_scl(scale_name, concert_pitch) cadence = old.Cadence( old.Chord( mel.Harmony( tuple(scale[idx] if idx <= 3 else scale[idx - 1] for idx in h) ), 1, ) for h in ([6], [5], [3], [2], [1, 5], [2], [3], [2]) ) test_cadence = pyquenzer.Instrument( concert_pitch, scale_name, {}, (1, 2, 3, 5, 6) ).mk_cadence(pitch_name, 1) self.assertEqual(cadence, test_cadence) for name in names: os.remove(name)
def test_chordify(self): chord0 = old.Chord(ji.JIHarmony([self.t0.pitch, self.t2.pitch]), rhy.Unit(1)) chord1 = old.Chord(ji.JIHarmony([self.t1.pitch, self.t3.pitch]), rhy.Unit(1)) cadence0 = old.Cadence([chord0, chord1]) self.assertEqual(cadence0, self.poly0.chordify()) chord0 = old.Chord(ji.JIHarmony([self.p0, self.p5]), rhy.Unit(0.5)) chord1 = old.Chord(ji.JIHarmony([self.p0, self.p1]), rhy.Unit(1.5)) chord2 = old.Chord(ji.JIHarmony([self.p0, self.p3]), rhy.Unit(1)) chord3 = old.Chord(ji.JIHarmony([self.p0]), rhy.Unit(1)) chord4 = old.Chord(ji.JIHarmony([self.p0, self.p2]), rhy.Unit(0.5)) chord5 = old.Chord(ji.JIHarmony([self.p0]), rhy.Unit(0.5)) expected = old.Cadence([chord0, chord1, chord2, chord3, chord4, chord4, chord5]) result = self.poly2.chordify( harmony_class=ji.JIHarmony, cadence_class=old.Cadence, add_longer=True ) for ex, re in zip(expected, result): print(ex, re) self.assertEqual(expected, result)
def create_cadence( self, stresses: tuple, does_siter_play: tuple, gender: bool, previous_signified: int, current_signified: int, following_signified: int, previous_side_prime: int, current_side_prime: int, following_side_prime: int, ) -> old.JICadence: if self.apply_with_header_if_header_exist: cadence = old.JICadence([]) else: cadence = old.JICadence([old.Chord(ji.JIHarmony([]), 0.5)]) divided_stresses = self.divide_stresses(stresses) amount_divisions = len(divided_stresses) is_with_modulation = current_signified != following_signified for idx, division in enumerate(divided_stresses): if idx == 0 and self.apply_with_header_if_header_exist: add_header = True else: add_header = False amount_stresses = len(division) is_with_resolution = not all(tuple(not s for s in division)) conditions_for_modulation = ( is_with_modulation, not is_with_resolution, idx + 1 == amount_divisions, ) if all(conditions_for_modulation): pattern = self.pattern[1][amount_stresses] cadence += self.convert_modulation_pattern( gender, current_signified, current_side_prime, following_signified, following_side_prime, pattern, add_header, ) else: pattern_idx = int(amount_stresses) if is_with_resolution: add_tail = True else: pattern_idx += 1 add_tail = False pattern = self.pattern[0][pattern_idx] cadence += self.convert_resolution_pattern( gender, current_signified, current_side_prime, pattern, add_header, add_tail, ) return old.JICadence(cadence)