void del_Event_cache(Event_cache* cache) { if (cache == NULL) return; del_AAtree(cache->cache); memory_free(cache); return; }
void del_Tuning_table(Tuning_table* tt) { if (tt == NULL) return; del_AAtree(tt->pitch_map); memory_free(tt); return; }
void del_Au_expressions(Au_expressions* ae) { if (ae == NULL) return; del_AAtree(ae->entries); memory_free(ae); return; }
void del_Channel_cv_state(Channel_cv_state* state) { if (state == NULL) return; del_AAtree(state->tree); memory_free(state); return; }
void del_Order_list(Order_list* ol) { if (ol == NULL) return; del_Vector(ol->pat_insts); del_AAtree(ol->index_map); memory_free(ol); return; }
void del_Connections(Connections* graph) { if (graph == NULL) return; del_AAtree(graph->nodes); memory_free(graph); return; }
void del_Input_map(Input_map* im) { if (im == NULL) return; del_AAtree(im->map); memory_free(im); return; }
void del_Environment(Environment* env) { if (env == NULL) return; del_AAiter(env->iter); del_AAtree(env->vars); memory_free(env); return; }
void del_Note_map(Note_map* map) { if (map == NULL) return; del_AAiter(map->iter); del_AAtree(map->map); memory_free(map); return; }
void del_Hit_map(Hit_map* map) { if (map == NULL) return; for (int i = 0; i < KQT_HITS_MAX; ++i) del_AAtree(map->hits[i]); memory_free(map); return; }
bool Environment_parse(Environment* env, Streader* sr) { assert(env != NULL); assert(sr != NULL); if (Streader_is_error_set(sr)) return false; if (!Streader_has_data(sr)) { AAtree_clear(env->vars); AAiter_change_tree(env->iter, env->vars); return true; } AAtree* new_vars = new_AAtree( (int (*)(const void*, const void*))strcmp, (void (*)(void*))del_Env_var); if (new_vars == NULL) { Streader_set_memory_error( sr, "Could not allocate memory for environment"); return false; } if (!Streader_read_list(sr, read_env_var, new_vars)) { del_AAtree(new_vars); return false; } AAiter_change_tree(env->iter, new_vars); AAtree* old_vars = env->vars; env->vars = new_vars; del_AAtree(old_vars); return true; }
static bool Tuning_table_build_pitch_map(Tuning_table* tt) { rassert(tt != NULL); AAtree* pitch_map = new_AAtree( (AAtree_item_cmp*)pitch_index_cmp, (AAtree_item_destroy*)memory_free); if (pitch_map == NULL) return false; for (int octave = 0; octave < KQT_TUNING_TABLE_OCTAVES; ++octave) { for (int note = 0; note < tt->note_count; ++note) { pitch_index* pi = &(pitch_index){ .cents = 0 }; pi->cents = tt->ref_pitch + tt->note_offsets[note] + tt->octave_offsets[octave]; pi->note = note; pi->octave = octave; if (!AAtree_contains(pitch_map, pi)) { pitch_index* pi_entry = memory_alloc_item(pitch_index); if (pi_entry == NULL) { del_AAtree(pitch_map); return false; } *pi_entry = *pi; if (!AAtree_ins(pitch_map, pi_entry)) { del_AAtree(pitch_map); return false; } } } } if (tt->pitch_map != NULL) del_AAtree(tt->pitch_map); tt->pitch_map = pitch_map; return true; } /** * Set a new note in the Tuning table using cents. * * Any existing note at the target index will be replaced. * The note will be set at no further than the first unoccupied index. * * \param tt The Tuning table -- must not be \c NULL. * \param index The index of the note to be set -- must be >= \c 0 and * less than the current note count. * \param cents The pitch ratio between the new note and reference pitch * in cents -- must be a finite value. */ static void Tuning_table_set_note_cents(Tuning_table* tt, int index, double cents); void Tuning_table_set_octave_width(Tuning_table* tt, double octave_width); static Tuning_table* new_Tuning_table(double ref_pitch, double octave_width) { rassert(ref_pitch > 0); rassert(isfinite(octave_width)); rassert(octave_width > 0); Tuning_table* tt = memory_alloc_item(Tuning_table); if (tt == NULL) return NULL; tt->pitch_map = NULL; tt->note_count = 0; tt->ref_note = 0; tt->ref_pitch = ref_pitch; tt->global_offset = 0; tt->centre_octave = 4; Tuning_table_set_octave_width(tt, octave_width); for (int i = 0; i < KQT_TUNING_TABLE_NOTES_MAX; ++i) tt->note_offsets[i] = 0; if (!Tuning_table_build_pitch_map(tt)) { memory_free(tt); return NULL; } return tt; }