void Padsynth_vstate_init(Voice_state* vstate, const Proc_state* proc_state) { rassert(vstate != NULL); rassert(proc_state != NULL); vstate->render_voice = Padsynth_vstate_render_voice; const Proc_padsynth* ps = (const Proc_padsynth*)proc_state->parent.device->dimpl; const int32_t sample_length = Padsynth_sample_map_get_sample_length(ps->sample_map); Padsynth_vstate* ps_vstate = (Padsynth_vstate*)vstate; ps_vstate->init_pitch = NAN; ps_vstate->pos = Random_get_index(vstate->rand_p, sample_length); return; }
const Sample_entry* Hit_map_get_entry( const Hit_map* map, int hit_index, double force, Random* random) { rassert(map != NULL); rassert(hit_index >= 0); rassert(hit_index < KQT_HITS_MAX); rassert(isfinite(force) || force == -INFINITY); rassert(random != NULL); AAtree* forces = map->hits[hit_index]; if (forces == NULL) { fprintf(stderr, "no forces\n"); return NULL; } Random_list* key = &(Random_list){ .force = force }; Random_list* greater = AAtree_get_at_least(forces, key); Random_list* smaller = AAtree_get_at_most(forces, key); Random_list* list = NULL; if (greater == NULL) list = smaller; else if (smaller == NULL) list = greater; else if (fabs(greater->force - force) < fabs(smaller->force - force)) list = greater; else list = smaller; if (list == NULL) return NULL; if (list->entry_count == 0) return NULL; const int index = Random_get_index(random, list->entry_count); return &list->entries[index]; }
const Sample_entry* Note_map_get_entry( const Note_map* map, double cents, double force, Random* random) { assert(map != NULL); assert(isfinite(cents)); assert(isfinite(force) || (isinf(force) && force < 0)); assert(random != NULL); Random_list* key = &(Random_list){ .force = force, .freq = NAN, .cents = cents }; Random_list* estimate_low = AAiter_get_at_most(map->iter, key); Random_list* choice = NULL; double choice_d = INFINITY; if (estimate_low != NULL) { choice = estimate_low; choice_d = distance(choice, key); double min_tone = key->cents - choice_d; Random_list* candidate = AAiter_get_prev(map->iter); while (candidate != NULL && candidate->cents >= min_tone) { double d = distance(candidate, key); if (d < choice_d) { choice = candidate; choice_d = d; min_tone = key->cents - choice_d; } candidate = AAiter_get_prev(map->iter); } } Random_list* estimate_high = AAiter_get_at_least(map->iter, key); if (estimate_high != NULL) { double d = distance(estimate_high, key); if (choice == NULL || choice_d > d) { choice = estimate_high; choice_d = d; } double max_tone = key->cents + choice_d; Random_list* candidate = AAiter_get_next(map->iter); while (candidate != NULL && candidate->cents <= max_tone) { d = distance(candidate, key); if (d < choice_d) { choice = candidate; choice_d = d; max_tone = key->cents + choice_d; } candidate = AAiter_get_next(map->iter); } } if (choice == NULL) { // fprintf(stderr, "empty map\n"); return NULL; } assert(choice->entry_count > 0); assert(choice->entry_count < NOTE_MAP_RANDOMS_MAX); // state->middle_tone = choice->freq; int index = Random_get_index(random, choice->entry_count); assert(index >= 0); // fprintf(stderr, "%d\n", index); return &choice->entries[index]; }