示例#1
0
bool Channel_cv_state_add_entry(Channel_cv_state* state, const char* var_name)
{
    rassert(state != NULL);
    rassert(var_name != NULL);
    rassert(strlen(var_name) < KQT_VAR_NAME_MAX);

    const Entry* entry = Entry_init(ENTRY_AUTO, var_name);

    if (!AAtree_contains(state->tree, entry))
    {
        Entry* new_entry = memory_alloc_item(Entry);
        if (new_entry == NULL)
            return false;

        *new_entry = *entry;

        if (!AAtree_ins(state->tree, new_entry))
        {
            memory_free(new_entry);
            return false;
        }
    }

    return true;
}
示例#2
0
static bool read_env_var(Streader* sr, int32_t index, void* userdata)
{
    assert(sr != NULL);
    (void)index;
    assert(userdata != NULL);

    AAtree* new_vars = userdata;

    Env_var* var = new_Env_var_from_string(sr);
    if (var == NULL)
        return false;

    if (AAtree_contains(new_vars, Env_var_get_name(var)))
    {
        Streader_set_error(
                sr, "Variable name %s is not unique", Env_var_get_name(var));
        del_Env_var(var);
        return false;
    }

    if (!AAtree_ins(new_vars, var))
    {
        Streader_set_memory_error(
                sr, "Could not allocate memory for environment");
        del_Env_var(var);
        return false;
    }

    return true;
}
示例#3
0
文件: Order_list.c 项目: kagu/kunquat
static bool read_piref(Streader* sr, int32_t index, void* userdata)
{
    rassert(sr != NULL);
    rassert(userdata != NULL);

    Order_list* ol = userdata;

    // Read the Pattern instance reference
    Pat_inst_ref* p = PAT_INST_REF_AUTO;
    if (!Streader_read_piref(sr, p))
        return false;

    // Check if the Pattern instance is already used
    Index_mapping* key = INDEX_MAPPING_AUTO;
    key->p = *p;
    key->ol_index = index;
    if (AAtree_contains(ol->index_map, key))
    {
        Streader_set_error(
                sr,
                "Duplicate occurrence of pattern instance"
                    " [%" PRId16 ", %" PRId16 "]",
                p->pat, p->inst);
        return false;
    }

    // Add the reference to our containers
    if (!Vector_append(ol->pat_insts, p))
    {
        Streader_set_memory_error(
                sr, "Could not allocate memory for order list");
        return false;
    }

    Index_mapping* im = new_Index_mapping(key);
    if (im == NULL || !AAtree_ins(ol->index_map, im))
    {
        memory_free(im);
        Streader_set_memory_error(
                sr, "Could not allocate memory for order list");
        return false;
    }

    return true;
}
示例#4
0
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;
}
示例#5
0
文件: Input_map.c 项目: kagu/kunquat
static bool read_entry(Streader* sr, int32_t index, void* userdata)
{
    rassert(sr != NULL);
    rassert(userdata != NULL);
    ignore(index);

    Input_map* im = userdata;

    int64_t in = 0;
    int64_t out = 0;
    if (!Streader_readf(sr, "[%i, %i]", &in, &out))
        return false;

    if (in < 0 || in >= im->num_inputs)
    {
        Streader_set_error(
                sr,
                "Input ID %" PRId64 " out of range [0, %" PRId32 ")",
                in, im->num_inputs);
        return false;
    }

    if (out < 0 || out >= im->num_outputs)
    {
        Streader_set_error(
                sr,
                "Output ID %" PRId64 " out of range [0, %" PRId32 ")",
                out, im->num_outputs);
        return false;
    }

    const Entry* key = ENTRY_KEY((int32_t)in);
    if (AAtree_contains(im->map, key))
    {
        Streader_set_error(sr, "Duplicate entry for input %" PRId64, in);
        return false;
    }

    Entry* entry = memory_alloc_item(Entry);
    if (entry == NULL)
    {
        Error_set(
                &sr->error,
                ERROR_MEMORY,
                "Could not allocate memory for input map");
        return false;
    }

    entry->input = (int32_t)in;
    entry->output = (int32_t)out;

    if (!AAtree_ins(im->map, entry))
    {
        memory_free(entry);
        Error_set(
                &sr->error,
                ERROR_MEMORY,
                "Could not allocate memory for input map");
        return false;
    }

    return true;
}
示例#6
0
static bool read_mapping(Streader* sr, int32_t index, void* userdata)
{
    rassert(sr != NULL);
    ignore(index);
    rassert(userdata != NULL);

    Hit_map* map = userdata;

    Random_list* list = memory_alloc_item(Random_list);
    if (list == NULL)
    {
        del_Hit_map(map);
        Streader_set_memory_error(
                sr, "Could not allocate memory for hit map random list");
        return false;
    }

    int64_t hit_index = -1;
    double force = NAN;

    if (!Streader_readf(sr, "[[%i,%f],", &hit_index, &force))
    {
        memory_free(list);
        return false;
    }

    if (hit_index < 0 || hit_index >= KQT_HITS_MAX)
    {
        Streader_set_error(
                sr,
                "Mapping hit index is outside range [0, %d)",
                KQT_HITS_MAX);
        memory_free(list);
        return false;
    }

    if (!isfinite(force))
    {
        Streader_set_error(
                sr,
                "Mapping force is not finite",
                KQT_HITS_MAX);
        memory_free(list);
        return false;
    }

    if (map->hits[hit_index] == NULL)
    {
        map->hits[hit_index] = new_AAtree(
                (AAtree_item_cmp*)Random_list_cmp, (AAtree_item_destroy*)memory_free);
        if (map->hits[hit_index] == NULL)
        {
            Streader_set_memory_error(
                    sr, "Could not allocate memory for hit map");
            memory_free(list);
            return false;
        }
    }

    list->force = force;
    list->entry_count = 0;
    if (AAtree_contains(map->hits[hit_index], list))
    {
        Streader_set_error(
                sr,
                "Duplicate hit map entry with hit index %" PRId64 ", force %.2f",
                hit_index,
                force);
        memory_free(list);
        return false;
    }
    if (!AAtree_ins(map->hits[hit_index], list))
    {
        Streader_set_memory_error(
                sr, "Could not allocate memory for hit map random list");
        memory_free(list);
        return false;
    }

    if (!Streader_read_list(sr, read_random_list_entry, list))
        return false;

    return Streader_match_char(sr, ']');
}
示例#7
0
static bool read_mapping(Streader* sr, int32_t index, void* userdata)
{
    assert(sr != NULL);
    ignore(index);
    assert(userdata != NULL);

    Note_map* map = userdata;

    Random_list* list = memory_alloc_item(Random_list);
    if (list == NULL)
    {
        Streader_set_memory_error(
                sr, "Could not allocate memory for note map entry");
        return false;
    }

    double cents = NAN;
    double force = NAN;

    if (!Streader_readf(sr, "[[%f,%f],", &cents, &force))
    {
        memory_free(list);
        return false;
    }

    if (!isfinite(cents))
    {
        Streader_set_error(sr, "Mapping cents is not finite");
        memory_free(list);
        return false;
    }

    if (!isfinite(force))
    {
        Streader_set_error(sr, "Mapping force is not finite");
        memory_free(list);
        return false;
    }

    list->freq = exp2(cents / 1200) * 440;
    list->cents = cents;
    list->force = force;
    list->entry_count = 0;
    if (AAtree_contains(map->map, list))
    {
        Streader_set_error(
                sr,
                "Duplicate note map entry with pitch %.2f, force %.2f",
                list->cents,
                list->force);
        memory_free(list);
        return false;
    }
    if (!AAtree_ins(map->map, list))
    {
        Streader_set_memory_error(
                sr, "Couldn't allocate memory for note map entry");
        memory_free(list);
        return false;
    }

    if (!Streader_read_list(sr, read_random_list_entry, list))
        return false;

    return Streader_match_char(sr, ']');
}