예제 #1
0
파일: drone.py 프로젝트: Kyntaz/sound-music
    def play(self, dur):
        times = sm.waves.tspan(dur)
        waves = []

        for start, wdur, lf, hf, amp, amp_freq, amp_phase in zip(
            self.starts, self.durs, self.low_freqs, self.high_freqs, self.amps, self.amp_freqs, self.amp_phases
        ):
            ss = lr.time_to_samples(start, sm.sound.SAMPLE_RATE)
            es = lr.time_to_samples(start + wdur, sm.sound.SAMPLE_RATE)
            es = min(es, self.so.samples.size - 1)
            samps = self.so.samples[ss:es]
            if samps.size <= 0:
                continue
            if hf < lf:
                hf, lf = lf, hf
            if es - ss > 0.1 * sm.sound.SAMPLE_RATE:
                samps = sm.effects.band_pass(SoundObject(samps), lf, hf).samples
            peak = np.max(np.abs(samps))
            if peak > 0.0:
                samps /= peak
            samp_dur = lr.samples_to_time(samps.size, sm.sound.SAMPLE_RATE)
            wave = np.interp(
                times, 
                np.linspace(0, samp_dur, samps.size),
                samps,
                period=samp_dur
            ) * amp
            mod = sm.waves.sin(times, amp_freq, 1.0, amp_phase)
            wave *= mod
            waves.append(SoundObject(wave))

        return sm.sound.join(waves)
예제 #2
0
def build_model(n, source: SoundObject):
    model = []
    history = []

    onsets = lr.onset.onset_detect(source.samples,
                                   sr=sm.sound.SAMPLE_RATE,
                                   backtrack=True,
                                   units="samples",
                                   wait=int(0.1 * sm.sound.SAMPLE_RATE / 512))
    for o1, o2 in zip(onsets, onsets[1:]):
        if o2 - o1 < sm.sound.SAMPLE_RATE * 0.1:
            continue
        so = SoundObject(source.samples[o1:o2])
        _, mtrack = so.track_pitch()

        pitch = max(so.get_f0(), 0)
        mag = max(np.mean(mtrack), 0)
        dur = max(so.duration, 0.15)

        note = Note(pitch, mag, dur)
        history.append(note)
        history = history[-n:]

        model.append(history)
    return model
예제 #3
0
def evolve(lso, n_generations, elitism, mut_prob, fitness_weights,
           fitness_params):
    npop = len(lso)
    population = [(so, fitness(so, fitness_weights, fitness_params))
                  for so in lso]

    for _ in range(n_generations):
        n_child = round(npop * (1 - elitism))
        pot_parents = copy.deepcopy(population)
        childs = []

        while len(childs) < n_child:
            if len(pot_parents) < 2: pot_parents = copy.deepcopy(population)
            parent0 = random.choices(pot_parents,
                                     weights=[
                                         score for _, score in pot_parents
                                     ],
                                     k=1)[0]
            pot_parents.remove(parent0)
            parent1 = random.choices(pot_parents,
                                     weights=[
                                         score for _, score in pot_parents
                                     ],
                                     k=1)[0]
            pot_parents.remove(parent1)
            child = crossover(parent0[0], parent1[0])
            while random.uniform(0, 1) < mut_prob:
                mut = random.choice(mutations)
                print(f"Mutating: {mut.__name__}")
                new_child = mut(child)
                if not np.isnan(new_child.samples).any():
                    child = new_child
                else:
                    print("Mutation Failed")
            try:
                child = SoundObject(
                    lr.effects.trim(child.get_normalize_to(1.0)))
            except:
                continue
            fit = fitness(child, fitness_weights, fitness_params)
            if np.isnan(fit) or np.isinf(fit): continue
            childs.append((child, fit))

        population = sorted(population, key=lambda ind: ind[1],
                            reverse=True)[:int(elitism * npop)] + childs
        print(max([s for _, s in population]))

    out = []
    for so, _ in population:
        ptrack, mtrack = so.track_pitch()
        pitch = lr.hz_to_midi(np.mean(ptrack))
        velocity = np.clip(np.mean(mtrack) * 127, 0, 127)
        out.append((so, pitch, velocity))
    return out
예제 #4
0
def band_pass(so: SoundObject, low, high, order=5):
    nyq = 0.5 * sm.sound.SAMPLE_RATE
    low = np.clip(low / nyq, 0.001, 0.999)
    high = np.clip(high / nyq, 0.001, 0.999)
    b, a = sp.signal.butter(order, [low, high], btype="band")
    out = sp.signal.lfilter(b, a, so.samples)
    return SoundObject(np.nan_to_num(out))
예제 #5
0
def crossover(so1: SoundObject, so2: SoundObject) -> SoundObject:
    so1 = copy.deepcopy(so1)
    so2 = copy.deepcopy(so2)
    env1 = sm.waves.sin(sm.waves.tspan(so1.duration), random.uniform(0.1, 4),
                        1.0, random.uniform(0, 2 * np.pi))

    env2 = sm.waves.sin(sm.waves.tspan(so2.duration), random.uniform(0.1, 4),
                        1.0, random.uniform(0, 2 * np.pi))

    so1.samples *= env1
    so2.samples *= env2
    so1.t = 0
    so2.t = random.uniform(0, so1.duration)

    return sm.sound.join(
        [so1.get_normalize_to(0.5),
         so2.get_normalize_to(0.5)])
예제 #6
0
def fitness_target(so: SoundObject, target: SoundObject):
    nso = so.get_padded(target.duration)
    spect1 = lr.stft(nso)
    spect2 = lr.stft(target.samples)
    spect1 /= np.max(spect1)
    spect2 /= np.max(spect2)
    dif = np.abs(spect1 - spect2)
    return np.mean(dif)
예제 #7
0
def get_room(so: SoundObject, dur):
    dur_samps = lr.time_to_samples(dur, sm.sound.SAMPLE_RATE)
    room = np.zeros(dur_samps, dtype=so.samples.dtype)
    silences = lr.onset.onset_detect(so.samples, sm.sound.SAMPLE_RATE,
        wait=int(dur_samps / 512), units="samples")
    count = 0
    for e,e2 in zip(silences, silences[1:]):
        ss = int(e + 0.01 * sm.sound.SAMPLE_RATE)
        es = int(min(ss + dur_samps, max(e2 - 0.01 * sm.sound.SAMPLE_RATE, 0)))
        if es < so.samples.size and es - ss > 0.1 * sm.sound.SAMPLE_RATE:
            response = so.samples[ss:es]
            room += SoundObject(response).get_padded(dur)
            count += 1
    if count == 0: return None
    room /= count
    room *= np.linspace(1, 0.0,  dur_samps)
    return SoundObject(room)
예제 #8
0
def mutate_chorus(so: SoundObject):
    samps = (Fx().chorus(random.uniform(0, 1), random.uniform(0, 1), [[
        random.uniform(40, 60),
        random.uniform(0, 1),
        random.uniform(0.2, 0.3),
        random.uniform(1, 5),
        random.choice(["s", "t"])
    ] for _ in range(random.randrange(1, 5))]))(so.samples)
    return SoundObject(samps)
예제 #9
0
파일: drone.py 프로젝트: Kyntaz/sound-music
def join_drones(drones, dur, amp):
    times = sm.waves.tspan(dur)
    waves = []
    for drone in drones:
        so = drone.play(dur)
        mod_freq = random.uniform(1 / MAX_DRONE_DUR, 1 / MIN_DRONE_DUR)
        mod_phase = random.uniform(0, 2*np.pi)
        mod = sm.waves.sin(times, mod_freq, amp / 2, mod_phase) + (amp / 2)
        so = SoundObject(so.samples * mod)
        waves.append(so)
    return sm.sound.join(waves)
예제 #10
0
파일: drone.py 프로젝트: Kyntaz/sound-music
    def play(self, dur):
        times = sm.waves.tspan(dur)
        waves = []

        for freq, phase, amp, amp_freq, amp_phase in zip(
            self.freqs, self.phases, self.amps, self.amp_freqs, self.amp_phases
        ):
            wave = sm.waves.sin(times, freq, amp, phase)
            mod = sm.waves.sin(times, amp_freq, 1.0, amp_phase)
            wave *= mod
            waves.append(SoundObject(wave))
        
        return sm.sound.join(waves)
예제 #11
0
    def play(self, npitch, nmag, ndur):
        note = Note(npitch, nmag, ndur)

        if note.pitch <= 0:
            samps = np.zeros(int(note.dur * sm.sound.SAMPLE_RATE))
            return SoundObject(samps)

        n_samples = int(note.dur * sm.sound.SAMPLE_RATE)
        factors = []
        for so, pitch, mag, dur in self.sounds:
            p_dif = (note.pitch - pitch)**2
            m_dif = (note.mag - mag)**2
            d_dif = (note.dur - dur)**2
            wei = 1 / np.sqrt(p_dif + m_dif + d_dif)
            samps = so.samples
            if samps.size > n_samples:
                samps = samps[:n_samples]
            elif samps.size < n_samples:
                samps = np.concatenate(
                    [samps, np.zeros(n_samples - samps.size)])
            factors.append([samps, wei])

        total = sum([w for _, w in factors])
        factors = sorted(factors, key=lambda fac: fac[1])[-MAX_SAMPLES:]
        out = np.zeros(n_samples)
        for samps, wei in factors:
            out += samps * wei / total

        pitch = SoundObject(out).get_f0()
        if pitch > 0:
            out = lr.effects.pitch_shift(
                out, sm.sound.SAMPLE_RATE,
                lr.hz_to_midi(note.pitch) - lr.hz_to_midi(pitch))

        oso = sm.effects.band_pass(SoundObject(out), note.pitch, 20000)
        return oso
예제 #12
0
파일: drone.py 프로젝트: Kyntaz/sound-music
def side_chain(point_durs_int, so: SoundObject):
    times = sm.waves.tspan(so.duration)
    curve = np.ones_like(so.samples)

    for start, end, intens in point_durs_int:
        p = (start + end) / 2
        w = end - start
        bump = sm.waves.bump(times, intens, p, w)
        curve -= bump

    curve = np.maximum(curve, 0.0)
    f = int(SWELL * so.duration * sm.sound.SAMPLE_RATE)
    l = curve.size
    curve = np.concatenate([
        np.linspace(0, 1, f),
        np.ones(l - 2 * f),
        np.linspace(1, 0, f)
    ]) * curve
    return SoundObject(so.samples * curve)
예제 #13
0
def mutate_reverse(so: SoundObject):
    samps = np.flip(so.samples)
    return SoundObject(samps)
예제 #14
0
def reverberate(room: SoundObject, so: SoundObject):
    samps = np.convolve(so.samples, room.samples, mode='same')
    return SoundObject(samps)
예제 #15
0
def mutate_pitch(so: SoundObject):
    samps = lr.effects.pitch_shift(so.samples, sm.sound.SAMPLE_RATE,
                                   random.uniform(-12.0, 12.0))
    return SoundObject(samps)
예제 #16
0
def mutate_compand(so: SoundObject):
    samps = (Fx().compand(random.uniform(0.1, 1.0), random.uniform(0.1, 1.0),
                          random.uniform(0.5, 2.0), random.uniform(-20, -3),
                          random.uniform(-20, -3),
                          random.uniform(-20, -3)))(so.samples)
    return SoundObject(samps)
예제 #17
0
def mutate_tempo(so: SoundObject):
    samps = lr.effects.time_stretch(so.samples, random.uniform(0.5, 2.0))
    return SoundObject(samps)
예제 #18
0
def mutate_bandreject(so: SoundObject):
    samps = (Fx().bandreject(random.uniform(20, 20e3),
                             random.uniform(0.1, 2.0)))(so.samples)
    return SoundObject(samps)
예제 #19
0
def mutate_distortion(so: SoundObject):
    a = random.uniform(0, 1)
    samps = np.clip(so.samples, -a, a)
    return SoundObject(samps)
예제 #20
0
def mutate_reverb(so: SoundObject):
    samps = (Fx().reverb(random.uniform(0, 100), random.uniform(0, 100),
                         random.uniform(0, 100), random.uniform(0, 100),
                         random.uniform(0, 100)))(so.samples)
    return SoundObject(samps)
예제 #21
0
def mutate_fragment(so: SoundObject):
    fr = random.randrange(0, so.samples.size - 0.1 * sm.sound.SAMPLE_RATE)
    to = random.randrange(fr + 0.1 * sm.sound.SAMPLE_RATE, so.samples.size)
    samps = so.samples[fr:to]
    return SoundObject(samps)