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