コード例 #1
0
ファイル: Order_list.c プロジェクト: kagu/kunquat
Order_list* new_Order_list(Streader* sr)
{
    rassert(sr != NULL);

    if (Streader_is_error_set(sr))
        return NULL;

    // Create the base structure
    Order_list* ol = memory_alloc_item(Order_list);
    if (ol == NULL)
    {
        Streader_set_memory_error(
                sr, "Could not allocate memory for order list");
        return NULL;
    }

    ol->pat_insts = NULL;
    ol->index_map = NULL;

    // Create Pattern instance reference vector
    ol->pat_insts = new_Vector(sizeof(Pat_inst_ref));
    if (ol->pat_insts == NULL)
    {
        Streader_set_memory_error(
                sr, "Could not allocate memory for order list");
        del_Order_list(ol);
        return NULL;
    }

    // Create reverse index of ol->pat_insts
    ol->index_map = new_AAtree(
            (AAtree_item_cmp*)Pat_inst_ref_cmp, (AAtree_item_destroy*)memory_free);
    if (ol->index_map == NULL)
    {
        Streader_set_memory_error(
                sr, "Could not allocate memory for order list");
        del_Order_list(ol);
        return NULL;
    }

    // List is empty by default
    if (!Streader_has_data(sr))
        return ol;

    // Read the list of Pattern instance references
    if (!Streader_read_list(sr, read_piref, ol))
    {
        del_Order_list(ol);
        return NULL;
    }

    return ol;
}
コード例 #2
0
ファイル: Note_map.c プロジェクト: cyberixae/kunquat
Note_map* new_Note_map_from_string(Streader* sr)
{
    assert(sr != NULL);

    if (Streader_is_error_set(sr))
        return NULL;

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

    map->map = NULL;
    map->iter = NULL;
    map->map = new_AAtree(
            (int (*)(const void*, const void*))Random_list_cmp,
            (void (*)(void*))del_Random_list);
    if (map->map == NULL)
    {
        del_Note_map(map);
        Streader_set_memory_error(
                sr, "Could not allocate memory for note map");
        return NULL;
    }

    map->iter = new_AAiter(map->map);
    if (map->iter == NULL)
    {
        del_Note_map(map);
        Streader_set_memory_error(
                sr, "Could not allocate memory for note map");
        return NULL;
    }

    if (!Streader_has_data(sr))
        return map;

    if (!Streader_read_list(sr, read_mapping, map))
    {
        del_Note_map(map);
        return NULL;
    }

    return map;
}
コード例 #3
0
ファイル: Channel_defaults_list.c プロジェクト: kagu/kunquat
Channel_defaults_list* new_Channel_defaults_list(Streader* sr)
{
    rassert(sr != NULL);

    if (Streader_is_error_set(sr))
        return NULL;

    Channel_defaults_list* cdl = memory_alloc_item(Channel_defaults_list);
    if (cdl == NULL)
    {
        Streader_set_memory_error(sr, "Could not allocate memory for channel defaults");
        return NULL;
    }

    for (int ch = 0; ch < KQT_CHANNELS_MAX; ++ch)
        Channel_defaults_init(&cdl->ch_defaults[ch]);

    if (!Streader_has_data(sr))
        return cdl;

    if (!Streader_read_list(sr, read_ch_defaults_item, cdl))
    {
        del_Channel_defaults_list(cdl);
        return NULL;
    }

    return cdl;
}
コード例 #4
0
ファイル: Environment.c プロジェクト: cyberixae/kunquat
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;
}
コード例 #5
0
Hit_map* new_Hit_map_from_string(Streader* sr)
{
    rassert(sr != NULL);

    if (Streader_is_error_set(sr))
        return NULL;

    Hit_map* map = memory_alloc_item(Hit_map);
    if (map == NULL)
    {
        Streader_set_memory_error(sr, "Could not allocate memory for hit map");
        return NULL;
    }

    for (int i = 0; i < KQT_HITS_MAX; ++i)
        map->hits[i] = NULL;

    if (!Streader_has_data(sr))
        return map;

    if (!Streader_read_list(sr, read_mapping, map))
    {
        del_Hit_map(map);
        return NULL;
    }

    return map;
}
コード例 #6
0
Au_expressions* new_Au_expressions(Streader* sr)
{
    rassert(sr != NULL);

    if (Streader_is_error_set(sr))
        return NULL;

    Au_expressions* ae = memory_alloc_item(Au_expressions);
    if (ae == NULL)
    {
        Streader_set_memory_error(
                sr, "Could not allocate memory for audio unit expressions");
        return NULL;
    }

    memset(ae->default_note_expr, '\0', KQT_VAR_NAME_MAX);
    ae->entries = new_AAtree(
            (AAtree_item_cmp*)strcmp, (AAtree_item_destroy*)del_Entry);
    if (ae->entries == NULL)
    {
        Streader_set_memory_error(
                sr, "Could not allocate memory for audio unit expressions");
        del_Au_expressions(ae);
        return NULL;
    }

    if (!Streader_read_dict(sr, read_expressions_def, ae))
    {
        rassert(Streader_is_error_set(sr));
        del_Au_expressions(ae);
        return NULL;
    }

    if (ae->default_note_expr[0] != '\0' &&
            !Au_expressions_get_proc_filter(ae, ae->default_note_expr))
    {
        Streader_set_error(
                sr,
                "Audio unit expressions do not contain the default expression %s",
                ae->default_note_expr);
        del_Au_expressions(ae);
        return NULL;
    }

    return ae;
}
コード例 #7
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;
}
コード例 #8
0
Connections* new_Connections_from_string(
        Streader* sr, Connection_level level, Au_table* au_table, Device* master)
{
    rassert(sr != NULL);
    rassert(au_table != NULL);
    rassert(master != NULL);

    if (Streader_is_error_set(sr))
        return NULL;

    Connections* graph = memory_alloc_item(Connections);
    if (graph == NULL)
    {
        Streader_set_memory_error(
                sr, "Could not allocate memory for connections");
        return NULL;
    }

    graph->nodes = NULL;
    graph->nodes = new_AAtree(
            (int (*)(const void*, const void*))Device_node_cmp,
            (void (*)(void*))del_Device_node);
    mem_error_if(graph->nodes == NULL, graph, NULL, sr);

    Device_node* master_node = NULL;
    if (level == CONNECTION_LEVEL_AU)
    {
        const Device* iface = Audio_unit_get_output_interface((Audio_unit*)master);
        master_node = new_Device_node("", au_table, iface);
    }
    else
    {
        master_node = new_Device_node("", au_table, master);
    }
    mem_error_if(master_node == NULL, graph, NULL, sr);
    mem_error_if(!AAtree_ins(graph->nodes, master_node), graph, master_node, sr);

    if (!Streader_has_data(sr))
        return graph;

    read_conn_data rcdata = { graph, level, au_table, master };
    if (!Streader_read_list(sr, read_connection, &rcdata))
    {
        del_Connections(graph);
        return NULL;
    }

    if (Connections_is_cyclic(graph))
    {
        Streader_set_error(sr, "The connection graph contains a cycle");
        del_Connections(graph);
        return NULL;
    }

    return graph;
}
コード例 #9
0
ファイル: Tuning_table.c プロジェクト: kagu/kunquat
Tuning_table* new_Tuning_table_from_string(Streader* sr)
{
    rassert(sr != NULL);

    if (Streader_is_error_set(sr))
        return NULL;

    Tuning_table* tt = new_Tuning_table(
            TUNING_TABLE_DEFAULT_REF_PITCH, TUNING_TABLE_DEFAULT_OCTAVE_WIDTH);
    if (tt == NULL)
    {
        Streader_set_memory_error(
                sr, "Couldn't allocate memory for tuning table");
        return NULL;
    }

    if (Streader_has_data(sr))
    {
        if (!Streader_read_dict(sr, read_tuning_table_item, tt))
        {
            del_Tuning_table(tt);
            return NULL;
        }

        if (tt->ref_note >= tt->note_count)
        {
            Streader_set_error(sr,
                     "Reference note doesn't exist: %d", tt->ref_note);
            del_Tuning_table(tt);
            return NULL;
        }
    }

    if (!Tuning_table_build_pitch_map(tt))
    {
        Streader_set_memory_error(sr, "Couldn't allocate memory for tuning table");
        del_Tuning_table(tt);
        return NULL;
    }

    return tt;
}
コード例 #10
0
ファイル: Num_list.c プロジェクト: kagu/kunquat
Num_list* new_Num_list_from_string(Streader* sr)
{
    rassert(sr != NULL);

    if (Streader_is_error_set(sr))
        return NULL;

    if (!Streader_has_data(sr))
        return NULL;

    Num_list* nl = memory_alloc_item(Num_list);
    if (nl == NULL)
    {
        Streader_set_memory_error(
            sr, "Could not allocate memory for number list");
        return NULL;
    }

    nl->len = 0;
    nl->res = 8;
    nl->nums = NULL;

    nl->nums = memory_alloc_items(double, nl->res);
    if (nl->nums == NULL)
    {
        del_Num_list(nl);
        Streader_set_memory_error(
            sr, "Could not allocate memory for number list");
        return NULL;
    }

    if (!Streader_read_list(sr, read_num, nl))
    {
        del_Num_list(nl);
        return NULL;
    }

    return nl;
}
コード例 #11
0
ファイル: Device.c プロジェクト: EdwardBetts/kunquat
bool Device_set_key(Device* device, const char* key, Streader* sr)
{
    assert(device != NULL);
    assert(key != NULL);
    assert(string_has_prefix(key, "i/") || string_has_prefix(key, "c/"));
    assert(sr != NULL);

    if (Streader_is_error_set(sr))
        return false;

    if (!Device_params_parse_value(device->dparams, key, sr))
        return false;

    if (device->dimpl != NULL && !Device_impl_set_key(device->dimpl, key + 2))
    {
        Streader_set_memory_error(
                sr, "Could not allocate memory for device key %s", key);
        return false;
    }

    return true;
}
コード例 #12
0
ファイル: Num_list.c プロジェクト: kagu/kunquat
static bool read_num(Streader* sr, int32_t index, void* userdata)
{
    rassert(sr != NULL);
    ignore(index);
    rassert(userdata != NULL);

    Num_list* nl = userdata;

    double num = NAN;
    if (!Streader_read_float(sr, &num))
        return false;

    if (!Num_list_append(nl, num))
    {
        del_Num_list(nl);
        Streader_set_memory_error(
            sr, "Could not allocate memory for number list");
        return false;
    }

    return true;
}
コード例 #13
0
ファイル: Environment.c プロジェクト: cyberixae/kunquat
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;
}
コード例 #14
0
Env_var* new_Env_var_from_string(Streader* sr)
{
    rassert(sr != NULL);

    if (Streader_is_error_set(sr))
        return NULL;

    char type_name[16] = "";
    char name[KQT_VAR_NAME_MAX] = "";

    if (!Streader_readf(
                sr,
                "[%s,%s,",
                READF_STR(16, type_name),
                READF_STR(KQT_VAR_NAME_MAX, name)))
        return NULL;

    if (!is_valid_var_name(name))
    {
        Streader_set_error(
                sr,
                "Illegal variable name %s"
                    " (Variable names may only contain"
                    " lower-case letters and underscores"
                    " (and digits as other than first characters))",
                name);
        return NULL;
    }

    Value* value = VALUE_AUTO;

    if (string_eq(type_name, "bool"))
    {
        value->type = VALUE_TYPE_BOOL;
        Streader_read_bool(sr, &value->value.bool_type);
    }
    else if (string_eq(type_name, "int"))
    {
        value->type = VALUE_TYPE_INT;
        Streader_read_int(sr, &value->value.int_type);
    }
    else if (string_eq(type_name, "float"))
    {
        value->type = VALUE_TYPE_FLOAT;
        Streader_read_float(sr, &value->value.float_type);
    }
    else if (string_eq(type_name, "timestamp"))
    {
        value->type = VALUE_TYPE_TSTAMP;
        Streader_read_tstamp(sr, &value->value.Tstamp_type);
    }
    else
    {
        Streader_set_error(
                sr,
                "Invalid type of environment variable %s: %s",
                name,
                type_name);
        return NULL;
    }

    if (!Streader_match_char(sr, ']'))
        return NULL;

    Env_var* var = new_Env_var(value->type, name);
    if (var == NULL)
    {
        Streader_set_memory_error(
                sr, "Could not allocate memory for environment variable");
        return NULL;
    }

    Env_var_set_value(var, value);

    return var;
}
コード例 #15
0
ファイル: Note_map.c プロジェクト: cyberixae/kunquat
static bool read_mapping(Streader* sr, int32_t index, void* userdata)
{
    assert(sr != NULL);
    (void)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_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;

    if (list->entry_count == 0)
    {
        Streader_set_error(sr, "Empty note mapping random list");
        return false;
    }

    return Streader_match_char(sr, ']');
}
コード例 #16
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, ']');
}