Ejemplo n.º 1
0
 def test_delay(self):
     rh0 = rhy.Unit(4)
     rhy_comp0 = rhy.Compound([rhy.Unit(2), rhy.Unit(4), rhy.Unit(1)])
     rhy_comp1 = rhy.Compound([rhy.Unit(4), rhy.Unit(8), rhy.Unit(2)])
     self.assertEqual(rh0.delay, time.Time(4))
     self.assertEqual(rhy_comp0.delay, time.Time(7))
     self.assertEqual(rhy_comp1.delay, time.Time(14))
Ejemplo n.º 2
0
    def __call__(self, sf_path: str, raw_data: tuple) -> tuple:
        """Return (old.Melody, bars)."""

        # convert raw data to relative - time - based melody
        melody = self._filter_raw_data_and_convert2melody(raw_data)

        # estimate tempo of soundfile
        tempo = self.estimate_tempo(sf_path)

        # divide tempo by 60 and multiply time values with factor to get values where one
        # whole notes equals 1, one halve note equals 0.5, etc.
        factor = tempo / 60
        melody.dur = rhy.Compound(melody.dur).stretch(factor)
        melody.delay = rhy.Compound(melody.delay).stretch(factor)

        # quantizise rhythmical values to precise numbers
        melody = self.estimate_rhythm(melody)

        if self.remove_repeating_pitches:
            melody = melody.tie()

        # detect metre of melody and adjust melody
        melody, metre, spread_metrical_loop = self.estimate_metre(melody)

        return melody, metre, spread_metrical_loop, tempo
Ejemplo n.º 3
0
 def estimate_rhythm(self, melody: old.Melody) -> tuple:
     melody.dur = rhy.Compound(melody.dur).stretch(self.stretch_factor)
     melody.delay = rhy.Compound(melody.delay).stretch(self.stretch_factor)
     melody = quantizise.quantisize_rhythm(
         melody, self.n_divisions, self.min_tone_size, self.min_rest_size
     )
     melody.dur = rhy.Compound(melody.dur).stretch(self.post_stretch_factor)
     melody.delay = rhy.Compound(melody.delay).stretch(self.post_stretch_factor)
     return melody
Ejemplo n.º 4
0
 def test_stretch(self):
     rh0 = rhy.Unit(2)
     rh1 = rhy.Unit(4)
     rh2 = rhy.Unit(1)
     self.assertEqual(rh0.stretch(2), rh1)
     self.assertEqual(rh0.stretch(0.5), rh2)
     rhy_comp0 = rhy.Compound([rhy.Unit(2), rhy.Unit(4), rhy.Unit(1)])
     rhy_comp1 = rhy.Compound([rhy.Unit(4), rhy.Unit(8), rhy.Unit(2)])
     rhy_comp2 = rhy.Compound([rhy.Unit(1), rhy.Unit(2), rhy.Unit(0.5)])
     self.assertEqual(rhy_comp0, rhy_comp1.stretch(0.5))
     self.assertEqual(rhy_comp0.stretch(2), rhy_comp1)
     self.assertEqual(rhy_comp0.stretch(0.5), rhy_comp2)
Ejemplo n.º 5
0
    def convert2relative(self):
        """Change time dimension of the object.

        Starting time of specific event becomes its Delay ,
        stoptime of specific event becomes its duration.
        """
        copy = self.copy()
        if self.time_measure == "absolute":
            delay = rhy.Compound(copy.delay).convert2relative()
            copy.dur = tuple(dur - delay for dur, delay in zip(self.dur, self.delay))
            delay.append(copy.dur[-1])
            copy.delay = delay
            copy._time_measure = "relative"
        return copy
Ejemplo n.º 6
0
    def convert2absolute(self) -> "AbstractLine":
        """Change time dimension of the object.

        Delay becomes the starting time of the specific event,
        duration becomes the stoptime of the specific event.
        """
        copy = self.copy()

        if self.time_measure == "relative":
            copy.delay = rhy.Compound(copy.delay).convert2absolute()
            stop = tuple((d + s) for d, s in zip(copy.delay, copy.dur))
            copy.dur = stop
            copy._time_measure = "absolute"

        return copy
Ejemplo n.º 7
0
    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
Ejemplo n.º 8
0
 def mk_sco(self, cadence: old.Cadence) -> str:
     lines = []
     abs_start = rhy.Compound(cadence.delay).convert2absolute()
     for event, start in zip(cadence, abs_start):
         if event.pitch and event.pitch != mel.TheEmptyPitch:
             duration = float(event.delay) + self.overlap
             release = self.release if self.release < duration else duration - 0.0001
             line = r"i1 {0} {1} ".format(start, duration)
             for pi in tuple(p for p in event.pitch
                             if p != mel.TheEmptyPitch):
                 sample_name, factor = self.find_sample(pi)
                 final_line = '{0} "{1}" {2} {3} {4}'.format(
                     line, sample_name, factor, self.volume, release)
                 lines.append(final_line)
     complete_duration = float(cadence.duration + 5)
     lines.append("i2 0 {0}".format(complete_duration))
     return "\n".join(lines)
Ejemplo n.º 9
0
 def test_convert2relative(self):
     r0 = rhy.Compound((0, 2, 4, 7, 8))
     r1 = rhy.Compound((2, 2, 3, 1))
     self.assertEqual(r0.convert2relative(), r1)
Ejemplo n.º 10
0
 def test_convert2absolute(self):
     r0 = rhy.Compound((2, 2, 3, 1))
     r1 = rhy.Compound((0, 2, 4, 7, 8))
     self.assertEqual(r0.convert2absolute(), r1[:-1])
     self.assertEqual(r0.convert2absolute(skiplast=False), r1)
Ejemplo n.º 11
0
    def __init__(
        self,
        voice: old.Melody,
        new_sample_positions: tuple,
        sample_per_change: tuple,
        make_envelope: bool,
        average_volume: float,
        min_volume: float,
        max_volume: float,
        duration: float,
        tempo_factor: float,
        shadow_time: float,
        crossfade_duration: float = 0.25,
        anticipation_time: float = 0,
        overlaying_time: float = 0,
        attack_duration: infit.InfIt = infit.Value(0.5),
        release_duration: infit.InfIt = infit.Value(0.5),
        random_seed: int = 100,
    ) -> None:

        assert max_volume > min_volume
        assert min_volume > average_volume

        if not isinstance(attack_duration, infit.InfIt):
            attack_duration = infit.Value(attack_duration)

        if not isinstance(release_duration, infit.InfIt):
            release_duration = infit.Value(release_duration)

        import random as random_module

        random_module.seed(random_seed)

        self.__random_module = random_module

        voice.delay = rhy.Compound(voice.delay).stretch(tempo_factor)
        voice.dur = rhy.Compound(voice.dur).stretch(tempo_factor)

        self.__sndinfo_per_sample = {
            sample: pyo.sndinfo(sample) for sample in set(sample_per_change)
        }
        self.__n_channels_per_sample = {
            sample: self.__sndinfo_per_sample[sample][3]
            for sample in self.__sndinfo_per_sample
        }
        self.__duration_per_sample = {
            sample: self.__sndinfo_per_sample[sample][1]
            for sample in self.__sndinfo_per_sample
        }
        self.__new_sample_positions = new_sample_positions
        self.__sample_per_change = sample_per_change
        self.__duration = duration
        self.__envelope = self.mk_envelope(
            voice,
            shadow_time,
            duration,
            average_volume,
            min_volume,
            max_volume,
            make_envelope,
            anticipation_time,
            overlaying_time,
        )
        self.__anticipation_time = anticipation_time
        self.__overlaying_time = overlaying_time
        self.__tempo_factor = tempo_factor
        self.__attack_duration = attack_duration
        self.__release_duration = release_duration
        self.__crossfade_duration = crossfade_duration
        self.__halved_crossfade_duration = crossfade_duration * 0.5
Ejemplo n.º 12
0
class MelodyTest(unittest.TestCase):
    p0 = ji.r(14, 9)
    p1 = ji.r(7, 4)
    d0 = rhy.Unit(400)
    d1 = rhy.Unit(800)
    t0 = old.Tone(p0, d0)
    t1 = old.Tone(p1, d1)
    mel0 = mel.Mel([p0] * 3)
    mel1 = mel.Mel([p1] * 3)
    rhy0 = rhy.Compound([d0] * 3)
    rhy1 = rhy.Compound([d1] * 3)
    melody0 = old.Melody([t0] * 3)

    def test_constructor(self):
        old.Melody([self.t0, self.t0, self.t0])

    def test_alternative_constructor(self):
        melody1 = old.Melody.from_parameter(self.mel0, self.rhy0)
        self.assertEqual(self.melody0, melody1)

    def test_duration(self):
        self.assertEqual(self.melody0.duration, sum(self.rhy0))
        melody1 = old.Melody([old.Rest(3)])
        self.assertEqual(melody1.duration, 3)

    def test_get_attributes(self):
        self.assertEqual(self.melody0.__get_pitch__(), self.mel0)
        self.assertEqual(self.melody0.__get_delay__(), self.rhy0)
        self.assertEqual(self.melody0.__get_duration__(), self.rhy0)

    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)

    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)

    def test_freq(self):
        self.assertEqual(self.melody0.freq, self.mel0.freq)

    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)

    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)

    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 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)

    def test_convert2absolute(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),
            )
        )
        self.assertEqual(self.melody0.convert2absolute(), melody_converted)

        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="relative",
        )
        self.assertEqual(self.melody0.convert2absolute(), melody_converted)

    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)

    def test_copy(self):
        melody0 = old.Melody([old.Tone(self.p0, self.d0), old.Tone(self.p0, self.d0)])
        self.assertEqual(melody0, melody0.copy())
Ejemplo n.º 13
0
    def make_natural_radio(
        voices_main: tuple,
        voices_side: tuple,
        tempo_factor: float,
        gender: bool,
        make_envelope: bool,
        samples: tuple,
        n_changes: int,
        crossfade_duration: float,
        anticipation_time: float,
        overlaying_time: float,
        average_volume: float,
        min_volume: float,
        max_volume: float,
        shadow_time: float,
        silent_channels: tuple,
        attack_duration: infit.InfIt,
        release_duration: infit.InfIt,
    ) -> dict:
        n_samples = len(samples)

        # make sure there are at least one sample but not more than three
        assert n_samples in (1, 2, 3)

        # are those asserts here really necessary?
        assert shadow_time <= anticipation_time
        assert shadow_time <= overlaying_time

        inner_voices = globals.POSITIVE_VOICES_POSITION
        outer_voices = globals.NEGATIVE_VOICES_POSITIONS

        duration = float(voices_main[0].duration * tempo_factor)
        duration += anticipation_time + overlaying_time

        if not gender:
            inner_voices, outer_voices = outer_voices, inner_voices

        delay_volume_pairs_per_voice = tuple(
            tuple((delay, tone.volume) for delay, tone in zip(
                rhy.Compound(melody.delay).stretch(
                    tempo_factor).convert2absolute(),
                melody,
            )) for melody in voices_main)

        delay_volume_pairs = functools.reduce(operator.add,
                                              delay_volume_pairs_per_voice)
        sorted_delay_volume_pairs = sorted(delay_volume_pairs,
                                           key=operator.itemgetter(1),
                                           reverse=True)

        change_positions = [0]
        for delay_volume_pair in sorted_delay_volume_pairs:
            if len(change_positions) - 1 == n_changes:
                break
            position = delay_volume_pair[0]
            if position not in change_positions:
                change_positions.append(position)

        change_positions = sorted(change_positions)

        sample_distributer_cycle = itertools.cycle((
            # for one sample
            (
                _CyclicPermutation((0, ) * 6), ),
            # for two samples
            (
                _CyclicPermutation((0, 1) * 3),
                _CyclicPermutation((0, 0, 1, 0, 1, 1)),
            ),
            # for three samples
            (
                _CyclicPermutation((0, 1, 2, 2, 1, 0)),
                _CyclicPermutation((0, 1, 2, 0, 1, 2)),
            ),
        )[n_samples - 1])

        sample_distribution_per_change = tuple(
            next(next(sample_distributer_cycle)) for n in range(n_changes + 1))
        sample_per_change_per_voice = tuple(
            tuple(samples[sample_idx] for sample_idx in voice)
            for voice in zip(*sample_distribution_per_change))

        init_attributes = {}

        for voice_type, voices in enumerate((voices_main, voices_side)):
            for voice_idx, voice in enumerate(voices):

                absolute_voice_idx = (inner_voices,
                                      outer_voices)[voice_type][voice_idx]

                if absolute_voice_idx not in silent_channels:

                    sound_engine = radio.RadioEngine(
                        voice,
                        change_positions,
                        sample_per_change_per_voice[absolute_voice_idx],
                        make_envelope,
                        average_volume,
                        min_volume,
                        max_volume,
                        duration,
                        tempo_factor,
                        shadow_time,
                        crossfade_duration,
                        anticipation_time=anticipation_time,
                        overlaying_time=overlaying_time,
                        attack_duration=attack_duration,
                        release_duration=release_duration,
                    )

                    voice_name = "natural_radio_{}".format(absolute_voice_idx)

                    init_attributes.update({
                        voice_name: {
                            "start": -anticipation_time,
                            "duration": duration,
                            "sound_engine": sound_engine,
                        }
                    })

        return init_attributes
Ejemplo n.º 14
0
 def delay(self) -> rhy.Compound:
     return rhy.Compound(obj.delay.copy() for obj in self)