示例#1
0
def _synthezise(name: str, instrument: str, scale: tuple) -> None:
    """make short sound files for string players to get used to intonation"""

    # (1) generate file where scale get played up & down
    duration_per_tone = 1.5
    rest_duration = 0.75
    melody = old.Melody([])
    for pitch in scale + tuple(reversed(scale))[1:]:
        melody.append(old.Tone(pitch, duration_per_tone))
        melody.append(old.Tone(mel.TheEmptyPitch, rest_duration))

    synth = synthesis.SimpleCsoundSinePlayer(melody)
    # for debugging:
    # synth.remove_files = False
    # synth.print_output = True
    synth.concert_pitch = globals_.CONCERT_PITCH
    synth.render("{}/soundfiles/wav/scale_{}".format(name, instrument))

    instrument_path = "{}/soundfiles/wav/{}".format(name, instrument)
    tools.igmkdir(instrument_path)

    # (2) generate for each scale degree one file
    single_tone_duration = 3
    duration_per_tone_rest_duration = 0.75
    for idx, pitch in enumerate(scale):
        melody = old.Melody(
            [
                old.Tone(pitch, single_tone_duration),
                old.Tone(mel.TheEmptyPitch, duration_per_tone_rest_duration),
            ]
        )
        synth = synthesis.SimpleCsoundSinePlayer(melody)
        synth.concert_pitch = globals_.CONCERT_PITCH
        synth.render("{}/{}".format(instrument_path, idx + 1))
示例#2
0
 def test_set_item(self):
     t0 = old.Tone(ji.r(1, 1), rhy.Unit(2))
     t1 = old.Tone(ji.r(2, 1), rhy.Unit(2))
     melody0 = old.Melody([t0, t1])
     melody1 = old.Melody([t1, t0])
     melody0[0], melody0[1] = melody1[0], melody1[1]
     self.assertEqual(melody0, melody1)
示例#3
0
    def test_find_exact_simultan_events(self):
        poly2 = old.Polyphon(
            (
                old.Melody([old.Tone(ji.r(1, 1), 2), old.Tone(ji.r(1, 1), 3)]),
                old.Melody([old.Tone(ji.r(3, 2), 3), old.Tone(ji.r(3, 2), 2)]),
                old.Melody([old.Tone(ji.r(4, 3), 1), old.Tone(ji.r(4, 3), 2)]),
            )
        )
        simultan_events4 = poly2.find_exact_simultan_events(0, 1)
        simultan_events4_expected = (
            old.Tone(ji.r(3, 2), 1, 1),
            old.Tone(ji.r(3, 2), 2, 2),
            old.Tone(ji.r(4, 3), 1, 1),
        )
        self.assertEqual(simultan_events4, simultan_events4_expected)

        simultan_events0 = self.poly0.find_exact_simultan_events(0, 0)
        self.assertEqual(simultan_events0, (self.poly0[1][0],))
        simultan_events1 = self.poly0.find_exact_simultan_events(0, 0, False)
        self.assertEqual(simultan_events1, (self.poly0[1].convert2absolute()[0],))
        simultan_events2 = self.poly1.find_exact_simultan_events(1, 0)
        simultan_events2_expected = (self.poly1[2][0], self.poly1[2][0])
        self.assertEqual(simultan_events2, simultan_events2_expected)
        simultan_events3 = self.poly1.find_exact_simultan_events(1, 1)
        simultan_events3_expected = (self.t8, self.t7, self.t7, self.t7, self.t2)
        self.assertEqual(simultan_events3, simultan_events3_expected)
示例#4
0
 def test_tie(self):
     melodyTest0 = old.Melody([old.Tone(self.t0.pitch, self.t0.delay * 3)])
     self.assertEqual(self.melody0.tie(), melodyTest0)
     melodyTest1 = old.Melody([old.Tone(self.t0.pitch, self.t0.delay * 2), self.t1])
     melody1 = old.Melody([self.t0, self.t0, self.t1])
     self.assertEqual(melody1.tie(), melodyTest1)
     melody2 = old.Melody([self.t0, self.t1, self.t0])
     self.assertEqual(melody2.tie(), melody2)
示例#5
0
class ToneSetTest(unittest.TestCase):
    p0 = ji.r(5, 4)
    p1 = ji.r(3, 2)
    p2 = ji.r(1, 1)
    p3 = ji.r(6, 5)
    p4 = ji.r(7, 4)
    p5 = ji.r(9, 8)
    t0 = old.Tone(p0, rhy.Unit(1))
    t1 = old.Tone(p1, rhy.Unit(1))
    t2 = old.Tone(p2, rhy.Unit(1))
    t3 = old.Tone(p3, rhy.Unit(1))
    t3 = old.Tone(p3, rhy.Unit(1))
    t4 = old.Tone(p4, rhy.Unit(1))
    t5 = old.Tone(p5, rhy.Unit(1))
    t0_set = old.Tone(p0, rhy.Unit(0), rhy.Unit(1))
    t1_set = old.Tone(p1, rhy.Unit(1), rhy.Unit(1))
    t2_set = old.Tone(p2, rhy.Unit(2), rhy.Unit(1))
    t3_set = old.Tone(p3, rhy.Unit(3), rhy.Unit(1))
    t4_set = old.Tone(p4, rhy.Unit(4), rhy.Unit(1))
    t5_set = old.Tone(p5, rhy.Unit(5), rhy.Unit(1))
    t6_set = old.Tone(p5, rhy.Unit(1), rhy.Unit(5))
    mel0 = old.Melody([t0, t1, t2, t3, t4, t5])
    mel1 = old.Melody([old.Rest(rhy.Unit(1)), t1, t2, t3, t4, t5])
    mel2 = old.Melody([t0, t1])
    set0 = old.ToneSet([t0_set, t1_set, t2_set, t3_set, t4_set, t5_set])
    set1 = old.ToneSet([t1_set, t2_set, t3_set, t4_set, t5_set])
    set2 = old.ToneSet([t1_set, t6_set, t2_set])

    def test_constructor(self):
        self.assertEqual(old.ToneSet.from_melody(ToneSetTest.mel0), ToneSetTest.set0)

    def test_converter(self):
        self.assertEqual(ToneSetTest.mel0, ToneSetTest.set0.convert2melody())
        self.assertEqual(ToneSetTest.mel1, ToneSetTest.set1.convert2melody())

    def test_pop_by(self):
        popped = ToneSetTest.set0.copy().pop_by_pitch(ToneSetTest.p0, ToneSetTest.p1)
        self.assertEqual(ToneSetTest.mel2, popped.convert2melody())
        popped = ToneSetTest.set0.copy().pop_by_start(rhy.Unit(0), rhy.Unit(1))
        self.assertEqual(ToneSetTest.mel2, popped.convert2melody())

    def test_pop_by_time(self):
        for t in self.set0.pop_by_time(1):
            self.assertEqual(t, self.t1_set)
        for t in self.set0.pop_by_time(1.5):
            self.assertEqual(t, self.t1_set)
        test_set0 = self.set2.pop_by_time(1.5)
        test_set_compare0 = old.ToneSet([self.t1_set, self.t6_set])
        test_set1 = self.set2.pop_by_time(2.7)
        test_set_compare1 = old.ToneSet([self.t2_set, self.t6_set])
        self.assertEqual(test_set0, test_set_compare0)
        self.assertEqual(test_set1, test_set_compare1)

    def test_pop_by_correct_dur_and_delay(self):
        poped_by = self.set0.pop_by_pitch(self.p0, self.p5)
        melody = poped_by.convert2melody()
        self.assertEqual(melody[0].delay, rhy.Unit(5))
        self.assertEqual(melody[0].duration, rhy.Unit(1))
示例#6
0
 def test_split(self):
     tone0 = old.Tone(ji.r(1, 1, 2), rhy.Unit(2), rhy.Unit(1))
     tone0B = old.Tone(ji.r(1, 1, 2), rhy.Unit(1), rhy.Unit(1))
     tone1 = old.Tone(ji.r(1, 1, 2), rhy.Unit(3), rhy.Unit(1))
     tone1B = old.Tone(ji.r(1, 1, 2), rhy.Unit(1), rhy.Unit(1))
     pause0 = old.Rest(rhy.Unit(1))
     pause1 = old.Rest(rhy.Unit(2))
     melody0 = old.Melody([tone0, tone1])
     melody1 = old.Melody([tone0B, pause0, tone1B, pause1])
     self.assertEqual(melody0.split(), melody1)
    def __call__(self, melody: old.Melody) -> old.Melody:
        new_melody = old.Melody([])

        for tone in melody:
            if not tone.pitch.is_empty and next(self.__add_tremolo_decider):
                rhythm = tone.delay
                duration_per_attack = []

                tremolo_size_generator = next(
                    self.__tremolo_size_generator_per_tone)

                while sum(duration_per_attack) < rhythm:
                    duration_per_attack.append(next(tremolo_size_generator))

                if len(duration_per_attack) > 1:
                    duration_per_attack = duration_per_attack[:-1]
                    difference = rhythm - sum(duration_per_attack)
                    duration_per_attack[-1] += difference
                else:
                    difference = sum(duration_per_attack) - rhythm
                    duration_per_attack[-1] -= difference

                for duration in duration_per_attack:
                    new_melody.append(
                        old.Tone(tone.pitch.copy(),
                                 duration,
                                 volume=tone.volume))

            else:
                new_melody.append(tone.copy())

        return new_melody
示例#8
0
 def detect_intervals_and_duration_pairs_per_tone_per_voice(
         voices: tuple) -> tuple:
     voices = tuple(old.Melody(v) for v in voices)
     interval_and_time_pairs_per_tone_per_voice = []
     for v_idx, voice in enumerate(voices):
         poly = old.Polyphon(v for v_idx1, v in enumerate(voices)
                             if v_idx1 != v_idx)
         melody = voice.copy()
         interval_and_time_pairs_per_tone = []
         for tone in melody.convert2absolute():
             start, stop = tone.delay, tone.duration
             simultan_events = functools.reduce(
                 operator.add,
                 tuple(m[:] for m in poly.cut_up_by_time(start, stop)))
             interval_and_time_pairs = []
             for simultan_event in simultan_events:
                 if not simultan_event.pitch.is_empty:
                     interval = simultan_event.pitch - tone.pitch
                     interval_and_time_pairs.append(
                         (interval, simultan_event.duration))
             interval_and_time_pairs_per_tone.append(
                 tuple(interval_and_time_pairs))
         interval_and_time_pairs_per_tone_per_voice.append(
             tuple(interval_and_time_pairs_per_tone))
     return tuple(interval_and_time_pairs_per_tone_per_voice)
示例#9
0
    def __call__(
        self,
        melody: old.Melody,
        is_consonance_per_tone: tuple,
        spectrum_profile_per_tone: tuple,
    ) -> old.Melody:
        new_melody = old.Melody([])

        new_is_consonance_per_tone = []
        new_spectrum_profile_per_tone = []

        for tone, is_consonance, spectrum_profile in zip(
            melody, is_consonance_per_tone, spectrum_profile_per_tone
        ):
            new_is_consonance_per_tone.append(is_consonance)
            new_spectrum_profile_per_tone.append(spectrum_profile)

            test0 = is_consonance or not self.__only_on_non_dissonant_pitches
            test0 = test0 and not tone.pitch.is_empty

            if test0 and next(self.__add_tremolo_decider):
                rhythm = tone.delay
                duration_per_attack = []

                tremolo_size_generator = next(self.__tremolo_size_generator_per_tone)

                while sum(duration_per_attack) < rhythm:
                    duration_per_attack.append(next(tremolo_size_generator))

                if len(duration_per_attack) > 1:
                    duration_per_attack = duration_per_attack[:-1]
                    difference = rhythm - sum(duration_per_attack)
                    duration_per_attack[-1] += difference
                else:
                    difference = sum(duration_per_attack) - rhythm
                    duration_per_attack[-1] -= difference

                is_first = True
                for duration in duration_per_attack:
                    if not is_first:
                        new_spectrum_profile_per_tone.append(spectrum_profile)
                        new_is_consonance_per_tone.append(False)
                        volume = tone.volume * self.__tremolo_volume_factor
                    else:
                        volume = tone.volume

                    new_melody.append(
                        old.Tone(tone.pitch.copy(), duration, volume=volume)
                    )

                    is_first = False

            else:
                new_melody.append(tone.copy())

        return (
            new_melody,
            tuple(new_is_consonance_per_tone),
            tuple(new_spectrum_profile_per_tone),
        )
示例#10
0
    def make_melody(self) -> old.Melody:
        if self._gender:
            self._melody_register = -self._melody_register

        melody_pitches = tuple(
            p if p.is_empty else p.register(p.octave + self._melody_register)
            for p in self._melody_pitches)

        transposition_pitch = (
            (globals.FEMALE_SOIL,
             globals.MALE_SOIL)[self._gender].pitches_per_vox_per_bar[
                 self._bar_number][0][0].normalize())
        if transposition_pitch.cents > 600:
            transposition_pitch = transposition_pitch.register(-1)

        melody_pitches = tuple(p if p.is_empty else p + transposition_pitch
                               for p in melody_pitches)

        if self._gender:
            melody_pitches = tuple(
                p if p.is_empty else p.inverse(transposition_pitch)
                for p in melody_pitches)

        distributed_beats = tools.euclid(
            self._n_bars * self._metrical_numbers[0], sum(self._melody_beats))
        absolute_rhythms = tools.accumulate_from_zero(self._melody_beats)
        distributed_rhythms = tuple(
            sum(distributed_beats[pos0:pos1])
            for pos0, pos1 in zip(absolute_rhythms, absolute_rhythms[1:]))
        absolute_rhythms = tools.accumulate_from_zero(distributed_rhythms)
        rhythms = tuple(
            sum(self._rhythms[0][pos0:pos1])
            for pos0, pos1 in zip(absolute_rhythms, absolute_rhythms[1:]))

        return old.Melody(tuple(map(old.Tone, melody_pitches, rhythms)))
def mk_harmonics_melodies(origin_melodies: tuple,
                          n_voices: int = 5,
                          max_harmonic: int = MAX_HARMONIC) -> tuple:
    """Make polyphonic movement of common (sub-)harmonics from the origin melodies.

    The resulting tuple contains as many melodies as previously declared with the
    n_voices argument.

    The n_voices argument may be helpful for making sure not having too many
    resulting voices what could happen when voices occasionally contain octaves
    or primes.
    """
    poly_per_interlocking = []
    origin_melodies = tuple(m.discard_rests().tie() for m in origin_melodies)
    for comb in itertools.combinations(origin_melodies, 2):
        cadence = old.Polyphon(comb).chordify(add_longer=True)
        harmonics_per_pitch = tuple(
            functools.reduce(
                operator.add,
                tuple(
                    find_common_harmonics(
                        p[0], p[1], gender=gender, border=max_harmonic)
                    for gender in (True, False)),
            ) if len(p) == 2 else tuple([]) for p in tuple(
                tuple(h) for h in cadence.pitch))
        poly = [[old.Rest(chord.delay) for chord in cadence]
                for n in range(n_voices)]
        for h_idx, harmonics in enumerate(harmonics_per_pitch):
            for p_idx, p in enumerate(harmonics[:n_voices]):
                poly[p_idx][h_idx] = p.convert2tone(cadence.delay[h_idx])

        poly = [old.Melody(melody) for melody in poly]
        poly_per_interlocking.append(old.Polyphon(poly))

    return tuple(poly_per_interlocking)
示例#12
0
    def __call__(self, melody: old.Melody) -> tuple:
        """Return (Melody, MetricalLoop) - pair."""
        possible_mappings = tuple({
            "violin": p[0],
            "viola": p[1],
            "cello": p[2]
        } for p in itertools.permutations(globals_.METRICAL_PRIMES))

        melody = old.Melody(melody)

        hof = crosstrainer.MultiDimensionalRating(fitness=[1, -1])

        c = 0
        for metrical_loop in self._available_metrical_loops:
            for mapping in possible_mappings:
                transformation = metrical_loop.transform_melody(
                    melody, mapping)
                relevant_data, fitness = transformation
                hof.append(relevant_data, *fitness)

            c += 1

        best = hof.convert2list()[-1]
        melody, spread_metrical_loop = best[0]

        # it's only a lambda function before for preventing to generate unused objects
        spread_metrical_loop = spread_metrical_loop()

        return melody, spread_metrical_loop.bars, spread_metrical_loop
示例#13
0
def harmonic_synthesis(poly_per_interlocking: tuple):
    import pyteq

    for poly_idx, poly in enumerate(poly_per_interlocking):
        for melody_idx, voice in enumerate(poly):
            voice = old.Melody(voice[:280])
            melody = [
                pyteq.PyteqTone(
                    ji.JIPitch(t.pitch, multiply=250),
                    t.delay,
                    t.duration,
                    volume=t.volume,
                    impedance=2,
                    q_factor=0.2,
                    string_length=9.9,
                    sustain_pedal=1,
                ) if t.pitch != mel.TheEmptyPitch else pyteq.PyteqTone(
                    t.pitch, t.delay, t.duration) for t in voice
            ]
            instr_range = tuple(n for n in range(10, 125))
            f = pyteq.Pianoteq(melody, available_midi_notes=instr_range)
            f.export2wav(
                "pianoteq_output/glitter_{0}_{1}".format(poly_idx, melody_idx),
                # preset='"Kalimba Spacey"',
                preset='"Celtic Harp Bright"',
            )
示例#14
0
    def _filter_raw_data_and_convert2melody(raw_data: tuple) -> old.Melody:
        melody = old.Melody([], time_measure="absolute")

        for tone in raw_data:
            pitch, start, stop_time, volume = tone

            if melody:
                stop_last_tone = melody[-1].duration
                difference = start - stop_last_tone

                if difference > 0:
                    melody.append(old.Tone(mel.TheEmptyPitch, stop_last_tone, start))

                elif difference < 0:
                    melody[-1].duration += difference

            else:
                if start != 0:
                    melody.append(old.Tone(mel.TheEmptyPitch, 0, start))

            melody.append(old.Tone(pitch, start, stop_time, volume=volume))

        melody = melody.convert2relative()

        if melody[0].pitch.is_empty:
            melody = melody[1:]

        return melody
示例#15
0
    def test_cut_up_by_time(self):
        t0 = old.Tone(ji.r(1, 1), rhy.Unit(2))
        t1 = old.Tone(ji.r(2, 1), rhy.Unit(2))
        t2 = old.Tone(ji.r(1, 1), rhy.Unit(1))
        r0 = old.Rest(1)

        melody0 = old.Melody([t0, t1, t1, t0, t1])
        melody1 = old.Melody([t1, t1, t0])
        melody2 = old.Melody([r0, t1, t1, t0])
        melody3 = old.Melody([t2, t1, t1, t0])
        melody4 = old.Melody([t1, t1, t2])

        self.assertEqual(melody0.cut_up_by_time(2, 8), melody1)
        self.assertEqual(melody0.cut_up_by_time(1, 8), melody2)
        self.assertEqual(melody0.cut_up_by_time(1, 8, add_earlier=True), melody3)
        self.assertEqual(melody0.cut_up_by_time(2, 7, hard_cut=True), melody4)
        self.assertEqual(melody0.cut_up_by_time(2, 7, hard_cut=False), melody1)
示例#16
0
 def test_convert2relative(self):
     melody_converted = old.Melody(
         (
             old.Tone(self.p0, self.d0 * 0, self.d0 * 1),
             old.Tone(self.p0, self.d0 * 1, self.d0 * 2),
             old.Tone(self.p0, self.d0 * 2, self.d0 * 3),
         ),
         time_measure="absolute",
     )
     self.assertEqual(melody_converted.convert2relative(), self.melody0)
示例#17
0
 def convert2voices(self, gender=True) -> tuple:
     len_voices = tuple(len(v) for v in self.voices)
     maxima = max(len_voices)
     rhythm_per_vox = [maxima // lv for lv in len_voices]
     return tuple(
         old.Melody(
             [
                 old.Tone(f.convert2pitch(gender=gender).normalize(), rhythm)
                 for f in vox
             ]
         )
         for vox, rhythm in zip(self.voices, rhythm_per_vox)
     )
    def quantizise(
        self,
        stretch_factor: float = 1,
        n_divisions: int = 8,
        min_tone_size: fractions.Fraction = 0,
        min_rest_size: fractions.Fraction = fractions.Fraction(1, 10),
    ) -> tuple:
        delays = rhy.Compound(tuple(
            t.delay for t in self.tones)).stretch(stretch_factor)
        tones = old.Melody(self.tones).copy()
        tones.delay = delays
        tones.dur = delays

        melody = quantizise.quantisize_rhythm(tones, n_divisions,
                                              min_tone_size, min_rest_size)
        return melody.pitch, melody.delay
示例#19
0
 def test_set_attributes(self):
     melody0 = old.Melody([])
     melody0.__set_pitch__(self.mel0)
     melody0.__set_delay__(self.rhy0)
     self.assertEqual(melody0.__get_pitch__(), self.mel0)
     self.assertEqual(melody0.__get_delay__(), self.rhy0)
     self.assertEqual(melody0.pitch, self.mel0)
     self.assertEqual(melody0.delay, self.rhy0)
     melody0.__set_pitch__(self.mel1)
     melody0.__set_delay__(self.rhy1)
     melody0.__set_duration__(self.rhy0)
     self.assertEqual(melody0.__get_pitch__(), self.mel1)
     self.assertEqual(melody0.__get_delay__(), self.rhy1)
     self.assertEqual(melody0.__get_duration__(), self.rhy0)
     self.assertEqual(melody0.pitch, self.mel1)
     self.assertEqual(melody0.delay, self.rhy1)
     self.assertEqual(melody0.dur, self.rhy0)
示例#20
0
    def __init__(
        self,
        tempo_factor: float,
        pitches: tuple,
        rhythm: binr.Compound,
        discard_rests: bool = True,
    ):
        self.__tempo_factor = tempo_factor
        self.__pitches = pitches
        self.__rhythm = rhythm

        melody = old.Melody(
            old.Tone(ji.JIPitch(p, multiply=globals.CONCERT_PITCH), r *
                     tempo_factor) if not p.is_empty else old.
            Rest(r * tempo_factor) for p, r in zip(pitches, rhythm))
        if discard_rests:
            melody = melody.discard_rests()
        super().__init__(melody, attack=0.08, decay=0.05, release=0.25)
示例#21
0
def simple_synthesis(melodies: tuple, make_diva=True):
    import random

    random.seed(10)

    import pyteq

    for idx, voice in enumerate(melodies):
        # voice = old.Melody(voice[:120]).tie()
        voice = old.Melody(voice[:200])
        if make_diva:
            melody_diva = [
                pyteq.DivaTone(
                    ji.JIPitch(t.pitch, multiply=250),
                    t.delay,
                    t.duration,
                    glissando=t.glissando,
                    volume=t.volume,
                ) if t.pitch != mel.TheEmptyPitch else pyteq.PyteqTone(
                    t.pitch, t.delay, t.duration) for t in voice
            ]
            pyteq.Diva(melody_diva).export(
                "pianoteq_output/test_diva{0}.mid".format(idx))
        melody_pteq = [
            pyteq.PyteqTone(
                ji.JIPitch(t.pitch, multiply=250),
                t.delay,
                t.duration,
                volume=t.volume,
                glissando=t.glissando,
                # impedance=random.uniform(2.801, 2.98),
                q_factor=random.uniform(0.201, 0.28),
                string_length=random.uniform(8.9, 9.8),
                sustain_pedal=1,
            ) if t.pitch != mel.TheEmptyPitch else pyteq.PyteqTone(
                t.pitch, t.delay, t.duration) for t in voice
        ]
        f = pyteq.Pianoteq(melody_pteq,
                           available_midi_notes=tuple(n
                                                      for n in range(20, 125)))
        f.export2wav("pianoteq_output/test{0}".format(idx),
                     preset='"Concert Harp Daily"')
示例#22
0
def quantisize_rhythm(
        melody: old.Melody,
        n_divisions: int = 8,
        min_tone_size: fractions.Fraction = 0,
        min_rest_size: fractions.Fraction = fractions.Fraction(1, 10),
) -> tuple:

    new_melody = []

    min_size = fractions.Fraction(1, n_divisions)
    left_over = 0

    for tone in melody:
        r = tone.delay

        if tone.pitch.is_empty:
            is_addable = r >= min_rest_size
        else:
            is_addable = r >= min_tone_size

        if is_addable:
            r += left_over
            left_over = 0
            quantisized = rhy.Unit(round(r * n_divisions) /
                                   n_divisions).fraction
            if quantisized == 0:
                quantisized = min_size

            new_tone = tone.copy()
            new_tone.delay = quantisized
            new_tone.duration = quantisized
            new_melody.append(new_tone)

        else:
            left_over += r

    new_melody[-1].delay += left_over
    new_melody[-1].duration += left_over

    return old.Melody(new_melody)
    def synthesize(
        self,
        stretch_factor: float = 1,
        n_divisions: int = 8,
        min_tone_size: fractions.Fraction = 0,
        min_rest_size: fractions.Fraction = fractions.Fraction(1, 10),
        concert_pitch: float = None,
        tie_notes: bool = False,
        remove_rests: bool = False,
    ) -> None:

        if not concert_pitch:
            concert_pitch = self.concert_pitch

        pitches, delays = self.quantizise(
            stretch_factor=stretch_factor,
            n_divisions=n_divisions,
            min_tone_size=min_tone_size,
            min_rest_size=min_rest_size,
        )

        melody = old.Melody([old.Tone(p, d) for p, d in zip(pitches, delays)])

        if remove_rests:
            melody = melody.discard_rests()

        if tie_notes:
            melody = melody.tie()

        sequence = []
        for tone in melody:
            p = tone.pitch
            d = tone.delay
            p.multiply = concert_pitch
            d *= 4
            sequence.append(midiplug.PyteqTone(p, d, d))

        midiplug.Pianoteq(sequence).export2wav("{}_transcription".format(
            self.name),
                                               preset='"Erard Player"')
    def _convert_data2melody(
            data: tuple,
            name: str,
            tempo_estimation_method: str = "essentia") -> tuple:

        tempo = Transcription.estimate_tempo(name,
                                             method=tempo_estimation_method)
        melody = old.Melody([], time_measure="absolute")

        for tone in data:
            pitch, start, stop_time, volume = tone

            if melody:
                stop_last_tone = melody[-1].duration
                difference = start - stop_last_tone

                if difference > 0:
                    melody.append(
                        old.Tone(mel.TheEmptyPitch, stop_last_tone, start))

                elif difference < 0:
                    melody[-1].duration += difference

            else:
                if start != 0:
                    melody.append(old.Tone(mel.TheEmptyPitch, 0, start))

            melody.append(old.Tone(pitch, start, stop_time, volume=volume))

        melody = melody.convert2relative()

        if melody[0].pitch.is_empty:
            melody = melody[1:]

        factor = tempo / 60

        melody.delay = tuple(d * factor for d in melody.delay)
        melody.dur = tuple(d * factor for d in melody.dur)

        return tuple(melody)
示例#25
0
 def test_cut_up_by_idx(self):
     poly0 = old.Polyphon(
         (
             old.Melody([old.Tone(ji.r(1, 1), 2), old.Tone(ji.r(1, 1), 3)]),
             old.Melody([old.Tone(ji.r(3, 2), 3), old.Tone(ji.r(3, 2), 2)]),
             old.Melody([old.Tone(ji.r(4, 3), 1), old.Tone(ji.r(4, 3), 2)]),
         )
     )
     poly0_cut = poly0.cut_up_by_idx(2, 1)
     poly0_cut_expected = old.Polyphon(
         (
             old.Melody([old.Tone(ji.r(1, 1), 1), old.Tone(ji.r(1, 1), 1)]),
             old.Melody([old.Tone(ji.r(3, 2), 2)]),
             old.Melody([old.Tone(ji.r(4, 3), 2)]),
         )
     )
     self.assertEqual(poly0_cut, poly0_cut_expected)
示例#26
0
    def __init__(
        self,
        chapter: int = 59,
        verse: int = "opening",
        time_transcriber=transcriptions.TimeTranscriber(),
        octave_of_first_pitch: int = 0,
        use_full_scale: bool = False,
        tempo_factor: float = 0.5,
        harmonic_field_max_n_pitches: int = 4,
        harmonic_field_minimal_harmonicity: float = 0.135,
        harmonic_tolerance:
        float = 0.5,  # a very low harmonic tolerance won't add any
        # additional harmonic pitches, while a very high tolerance will try to add as many
        # additional harmonic pitches as possible.
        harmonic_pitches_add_artifical_harmonics: bool = True,
        harmonic_pitches_add_normal_pitches: bool = True,
        harmonic_pitches_tonality_flux_maximum_octave_difference_from_melody_pitch:
        tuple = (
            1,
            0,
        ),
        harmonic_pitches_complex_interval_helper_maximum_octave_difference_from_melody_pitch:
        tuple = (
            1,
            0,
        ),
        max_rest_size_to_ignore: fractions.Fraction = fractions.Fraction(1, 4),
        maximum_deviation_from_center: float = 0.5,
        # rhythmical orientation data
        ro_temperature:
        float = 0.7,  # a low temperature increases the chance for a
        # beat to get added.
        ro_density: float = 0.5,  # a high density value increases the amount of
        # orientation beats.
        area_density_maker: infit.InfIt = None,  # a higher value
        # leads to more perforated melodic pitches.
        area_density_reference_size: fractions.Fraction = fractions.Fraction(
            1, 2),
        area_min_split_size: fractions.Fraction = fractions.Fraction(1, 4),
    ) -> None:
        if area_density_maker is None:
            area_density_maker = infit.Gaussian(0.25, 0.075)

        self.transcription = self._get_transcription(
            chapter=chapter,
            verse=verse,
            time_transcriber=time_transcriber,
            octave_of_first_pitch=octave_of_first_pitch,
            use_full_scale=use_full_scale,
        )
        self._transcription_melody = old.Melody(tuple(self.transcription[:]))
        self.areas = areas.Areas.from_melody(
            self._transcription_melody,
            self.transcription.spread_metrical_loop,
            area_density_maker,
            area_density_reference_size,
            area_min_split_size,
        )
        self.chapter = chapter
        self.verse = verse
        self.tempo_factor = tempo_factor
        self.bread = breads.Bread.from_melody(
            old.Melody(self.transcription).copy(),
            self.bars,
            max_rest_size_to_ignore,
            maximum_deviation_from_center,
        )

        self.assign_harmonic_pitches_to_slices(
            harmonic_tolerance,
            harmonic_pitches_add_artifical_harmonics,
            harmonic_pitches_add_normal_pitches,
            harmonic_pitches_tonality_flux_maximum_octave_difference_from_melody_pitch,
            harmonic_pitches_complex_interval_helper_maximum_octave_difference_from_melody_pitch,
        )
        self.assign_harmonic_fields_to_slices(
            harmonic_field_max_n_pitches, harmonic_field_minimal_harmonicity)

        self.rhythmic_orientation_indices = self._detect_rhythmic_orientation(
            temperature=ro_temperature, density=ro_density)

        self.melodic_orientation = self._make_melodic_orientation_system()
        self.rhythmic_orientation = self._make_rhythmic_orientation_system()

        super().__init__()

        self.attach(
            violin=strings.SilentStringMaker(globals_.VIOLIN),
            viola=strings.SilentStringMaker(globals_.VIOLA),
            cello=strings.SilentStringMaker(globals_.CELLO),
            keyboard=keyboard.SilentKeyboardMaker(),
        )
示例#27
0
    def test_cut_up_by_time(self):
        poly0 = old.Polyphon(
            (
                old.Melody([old.Tone(ji.r(1, 1), 2), old.Tone(ji.r(1, 1), 3)]),
                old.Melody([old.Tone(ji.r(3, 2), 3), old.Tone(ji.r(3, 2), 2)]),
                old.Melody([old.Tone(ji.r(4, 3), 1), old.Tone(ji.r(4, 3), 2)]),
            )
        )
        poly0_cut = poly0.cut_up_by_time(1, 3)
        poly0_cut_expected = old.Polyphon(
            (
                old.Melody([old.Tone(ji.r(1, 1), 1), old.Tone(ji.r(1, 1), 1)]),
                old.Melody([old.Tone(ji.r(3, 2), 2)]),
                old.Melody([old.Tone(ji.r(4, 3), 2)]),
            )
        )
        self.assertEqual(poly0_cut, poly0_cut_expected)

        poly1_cut = poly0.cut_up_by_time(1, 3, add_earlier=False)
        poly1_cut_expected = old.Polyphon(
            (
                old.Melody([old.Rest(1), old.Tone(ji.r(1, 1), 1)]),
                old.Melody([old.Rest(2)]),
                old.Melody([old.Tone(ji.r(4, 3), 2)]),
            )
        )
        self.assertEqual(poly1_cut, poly1_cut_expected)

        poly2_cut = poly0.cut_up_by_time(1, 3, hard_cut=False)
        poly2_cut_expected = old.Polyphon(
            (
                old.Melody([old.Tone(ji.r(1, 1), 2), old.Tone(ji.r(1, 1), 3)]),
                old.Melody([old.Tone(ji.r(3, 2), 3)]),
                old.Melody([old.Rest(1), old.Tone(ji.r(4, 3), 2)]),
            )
        )
        self.assertEqual(poly2_cut[2], poly2_cut_expected[2])
示例#28
0
class PolyTest(unittest.TestCase):
    p0 = ji.r(5, 4)
    p1 = ji.r(3, 2)
    p2 = ji.r(1, 1)
    p3 = ji.r(6, 5)
    p4 = ji.r(7, 4)
    p5 = ji.r(9, 8)
    t0 = old.Tone(p0, rhy.Unit(1))
    t1 = old.Tone(p1, rhy.Unit(1))
    t2 = old.Tone(p2, rhy.Unit(1))
    t3 = old.Tone(p3, rhy.Unit(1))
    t3 = old.Tone(p3, rhy.Unit(1))
    t4 = old.Tone(p4, rhy.Unit(1))
    t5 = old.Tone(p5, rhy.Unit(1))
    t6 = old.Tone(p0, rhy.Unit(2))
    t7 = old.Tone(p0, rhy.Unit(0.5))
    t8 = old.Tone(p0, rhy.Unit(1.5))
    t9 = old.Tone(p1, rhy.Unit(1.5))
    t10 = old.Tone(p5, rhy.Unit(0.5))
    t11 = old.Tone(p2, rhy.Unit(1))
    melody0 = old.Melody((t0, t1))
    melody1 = old.Melody((t2, t3))
    melody2 = old.Melody((t6, t6, t0, t7))  # duration 5.5
    melody3 = old.Melody((t7, t6, t2, t2))  # duration 4.5
    melody4 = old.Melody((t7, t7, t7, t2, t2))  # duration 3.5
    melody5 = old.Melody((t10, t9, t3, t8, t0))  # duration 5.5
    melody6 = old.Melody((t6, t6, t2, t7))  # duration 5.5

    poly0 = old.Polyphon([melody0, melody1])
    poly1 = old.Polyphon([melody2, melody3, melody4])
    poly2 = old.Polyphon([melody6, melody5])

    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 test_find_simultan_events(self):
        simultan_events0 = self.poly0.find_simultan_events(0, 0)
        self.assertEqual(simultan_events0, (self.poly0[1].convert2absolute()[0],))
        simultan_events1 = self.poly0.find_simultan_events(1, 1)
        self.assertEqual(simultan_events1, (self.poly0[0].convert2absolute()[1],))
        simultan_events2 = self.poly1.find_simultan_events(0, 1)
        simultan_events2_comp = (
            self.poly1[1].convert2absolute()[1],
            self.poly1[1].convert2absolute()[2],
            self.poly1[1].convert2absolute()[3],
            self.poly1[2].convert2absolute()[-2],
            self.poly1[2].convert2absolute()[-1],
        )
        self.assertEqual(simultan_events2, simultan_events2_comp)
        simultan_events3 = self.poly1.find_simultan_events(1, 1)
        simultan_events3_comp = (
            self.poly1[0].convert2absolute()[0],
            self.poly1[0].convert2absolute()[1],
            self.poly1[2].convert2absolute()[1],
            self.poly1[2].convert2absolute()[2],
            self.poly1[2].convert2absolute()[3],
        )
        self.assertEqual(simultan_events3, simultan_events3_comp)

    def test_find_exact_simultan_events(self):
        poly2 = old.Polyphon(
            (
                old.Melody([old.Tone(ji.r(1, 1), 2), old.Tone(ji.r(1, 1), 3)]),
                old.Melody([old.Tone(ji.r(3, 2), 3), old.Tone(ji.r(3, 2), 2)]),
                old.Melody([old.Tone(ji.r(4, 3), 1), old.Tone(ji.r(4, 3), 2)]),
            )
        )
        simultan_events4 = poly2.find_exact_simultan_events(0, 1)
        simultan_events4_expected = (
            old.Tone(ji.r(3, 2), 1, 1),
            old.Tone(ji.r(3, 2), 2, 2),
            old.Tone(ji.r(4, 3), 1, 1),
        )
        self.assertEqual(simultan_events4, simultan_events4_expected)

        simultan_events0 = self.poly0.find_exact_simultan_events(0, 0)
        self.assertEqual(simultan_events0, (self.poly0[1][0],))
        simultan_events1 = self.poly0.find_exact_simultan_events(0, 0, False)
        self.assertEqual(simultan_events1, (self.poly0[1].convert2absolute()[0],))
        simultan_events2 = self.poly1.find_exact_simultan_events(1, 0)
        simultan_events2_expected = (self.poly1[2][0], self.poly1[2][0])
        self.assertEqual(simultan_events2, simultan_events2_expected)
        simultan_events3 = self.poly1.find_exact_simultan_events(1, 1)
        simultan_events3_expected = (self.t8, self.t7, self.t7, self.t7, self.t2)
        self.assertEqual(simultan_events3, simultan_events3_expected)

    def test_cut_up_by_time(self):
        poly0 = old.Polyphon(
            (
                old.Melody([old.Tone(ji.r(1, 1), 2), old.Tone(ji.r(1, 1), 3)]),
                old.Melody([old.Tone(ji.r(3, 2), 3), old.Tone(ji.r(3, 2), 2)]),
                old.Melody([old.Tone(ji.r(4, 3), 1), old.Tone(ji.r(4, 3), 2)]),
            )
        )
        poly0_cut = poly0.cut_up_by_time(1, 3)
        poly0_cut_expected = old.Polyphon(
            (
                old.Melody([old.Tone(ji.r(1, 1), 1), old.Tone(ji.r(1, 1), 1)]),
                old.Melody([old.Tone(ji.r(3, 2), 2)]),
                old.Melody([old.Tone(ji.r(4, 3), 2)]),
            )
        )
        self.assertEqual(poly0_cut, poly0_cut_expected)

        poly1_cut = poly0.cut_up_by_time(1, 3, add_earlier=False)
        poly1_cut_expected = old.Polyphon(
            (
                old.Melody([old.Rest(1), old.Tone(ji.r(1, 1), 1)]),
                old.Melody([old.Rest(2)]),
                old.Melody([old.Tone(ji.r(4, 3), 2)]),
            )
        )
        self.assertEqual(poly1_cut, poly1_cut_expected)

        poly2_cut = poly0.cut_up_by_time(1, 3, hard_cut=False)
        poly2_cut_expected = old.Polyphon(
            (
                old.Melody([old.Tone(ji.r(1, 1), 2), old.Tone(ji.r(1, 1), 3)]),
                old.Melody([old.Tone(ji.r(3, 2), 3)]),
                old.Melody([old.Rest(1), old.Tone(ji.r(4, 3), 2)]),
            )
        )
        self.assertEqual(poly2_cut[2], poly2_cut_expected[2])

    def test_cut_up_by_idx(self):
        poly0 = old.Polyphon(
            (
                old.Melody([old.Tone(ji.r(1, 1), 2), old.Tone(ji.r(1, 1), 3)]),
                old.Melody([old.Tone(ji.r(3, 2), 3), old.Tone(ji.r(3, 2), 2)]),
                old.Melody([old.Tone(ji.r(4, 3), 1), old.Tone(ji.r(4, 3), 2)]),
            )
        )
        poly0_cut = poly0.cut_up_by_idx(2, 1)
        poly0_cut_expected = old.Polyphon(
            (
                old.Melody([old.Tone(ji.r(1, 1), 1), old.Tone(ji.r(1, 1), 1)]),
                old.Melody([old.Tone(ji.r(3, 2), 2)]),
                old.Melody([old.Tone(ji.r(4, 3), 2)]),
            )
        )
        self.assertEqual(poly0_cut, poly0_cut_expected)
示例#29
0
 def test_copy(self):
     melody0 = old.Melody([old.Tone(self.p0, self.d0), old.Tone(self.p0, self.d0)])
     self.assertEqual(melody0, melody0.copy())
示例#30
0
 def test_add(self):
     compound = old.Melody([self.t0, self.t1, self.t1])
     melody0 = old.Melody([self.t0])
     melody1 = old.Melody([self.t1] * 2)
     self.assertEqual(melody0 + melody1, compound)