コード例 #1
0
bool read_received_events(Streader* sr, int32_t index, void* userdata)
{
    assert(sr != NULL);
    (void)index;
    assert(userdata != NULL);

    int32_t* expected = userdata;
    double actual = NAN;

    const char* event_name = (*expected % 16 == 0) ? "n+" : "vs";

    if (!(Streader_readf(sr, "[0, [") &&
                Streader_match_string(sr, event_name) &&
                Streader_readf(sr, ", %f]]", &actual))
       )
        return false;

    if ((int)round(actual) != *expected)
    {
        Streader_set_error(
                sr,
                "Received argument %" PRId64 " instead of %" PRId32,
                actual, *expected);
        return false;
    }

    *expected = (int)round(actual) + 1;

    return true;
}
コード例 #2
0
END_TEST


static bool test_reported_force(Streader* sr, double expected)
{
    assert(sr != NULL);

    double actual = NAN;

    if (!(Streader_readf(sr, "[[0, [") &&
                Streader_match_string(sr, "qf") &&
                Streader_readf(sr, ", null]], [0, [") &&
                Streader_match_string(sr, "Af") &&
                Streader_readf(sr, ", %f]]]", &actual)))
        return false;

    if (fabs(actual - expected) > 0.1)
    {
        Streader_set_error(
                sr, "Expected force %.4f, got %.4f", expected, actual);
        return false;
    }

    return true;
}
コード例 #3
0
bool read_received_events_bind(Streader* sr, int32_t index, void* userdata)
{
    assert(sr != NULL);
    (void)index;
    assert(userdata != NULL);

    int32_t* expected = userdata;
    double actual = NAN;

    if (index == 0 && *expected == 0)
    {
        return Streader_readf(sr, "[0, [") &&
            Streader_match_string(sr, "#") &&
            Streader_match_char(sr, ',') &&
            Streader_read_string(sr, 0, NULL) &&
            Streader_readf(sr, "]]");
    }

    if (!(Streader_readf(sr, "[0, [") &&
                Streader_match_string(sr, "n+") &&
                Streader_readf(sr, ", %f]]", &actual))
       )
        return false;

    if ((int)round(actual) != *expected)
    {
        Streader_set_error(
                sr,
                "Received argument %.0f instead of %" PRId32,
                actual, *expected);
        return false;
    }

    *expected = (int)round(actual) + 1;

    return true;
}
コード例 #4
0
ファイル: Tuning_table.c プロジェクト: kagu/kunquat
static bool Streader_read_tuning(Streader* sr, double* cents)
{
    rassert(sr != NULL);
    rassert(cents != NULL);

    if (Streader_is_error_set(sr))
        return false;

    if (Streader_try_match_char(sr, '['))
    {
        int64_t num = 0;
        int64_t den = 0;
        if (!Streader_readf(sr, "%i,%i]", &num, &den))
            return false;

        if (num <= 0)
        {
            Streader_set_error(sr, "Numerator must be positive");
            return false;
        }
        if (den <= 0)
        {
            Streader_set_error(sr, "Denominator must be positive");
            return false;
        }

        *cents = log2((double)num / (double)den) * 1200;
    }
    else
    {
        if (!Streader_read_float(sr, cents))
            return false;

        if (!isfinite(*cents))
        {
            Streader_set_error(sr, "Cents value must be finite");
            return false;
        }
    }

    return true;
}
コード例 #5
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;
}
コード例 #6
0
static bool read_connection(Streader* sr, int32_t index, void* userdata)
{
    rassert(sr != NULL);
    rassert(userdata != NULL);
    ignore(index);

    read_conn_data* rcdata = userdata;

    char src_name[KQT_DEVICE_NODE_NAME_MAX] = "";
    char dest_name[KQT_DEVICE_NODE_NAME_MAX] = "";
    if (!Streader_readf(
                sr,
                "[%s,%s]",
                READF_STR(KQT_DEVICE_NODE_NAME_MAX, src_name),
                READF_STR(KQT_DEVICE_NODE_NAME_MAX, dest_name)))
        return false;

    int src_port = validate_connection_path(
            sr, src_name, rcdata->level, DEVICE_PORT_TYPE_SEND);
    int dest_port = validate_connection_path(
            sr, dest_name, rcdata->level, DEVICE_PORT_TYPE_RECV);
    if (Streader_is_error_set(sr))
        return false;

    if (rcdata->level == CONNECTION_LEVEL_AU)
    {
        if (string_eq(src_name, ""))
            strcpy(src_name, "Iin");
    }

    if (AAtree_get_exact(rcdata->graph->nodes, src_name) == NULL)
    {
        const Device* actual_master = rcdata->master;
        if ((rcdata->level == CONNECTION_LEVEL_AU) &&
                string_eq(src_name, "Iin"))
            actual_master = Audio_unit_get_input_interface((Audio_unit*)rcdata->master);

        Device_node* new_src = new_Device_node(
                src_name, rcdata->au_table, actual_master);

        mem_error_if(new_src == NULL, rcdata->graph, NULL, sr);
        mem_error_if(
                !AAtree_ins(rcdata->graph->nodes, new_src),
                rcdata->graph,
                new_src,
                sr);
    }
    Device_node* src_node = AAtree_get_exact(rcdata->graph->nodes, src_name);

    if (AAtree_get_exact(rcdata->graph->nodes, dest_name) == NULL)
    {
        Device_node* new_dest = new_Device_node(
                dest_name, rcdata->au_table, rcdata->master);

        mem_error_if(new_dest == NULL, rcdata->graph, NULL, sr);
        mem_error_if(
                !AAtree_ins(rcdata->graph->nodes, new_dest),
                rcdata->graph,
                new_dest,
                sr);
    }
    Device_node* dest_node = AAtree_get_exact(rcdata->graph->nodes, dest_name);

    rassert(src_node != NULL);
    rassert(dest_node != NULL);
    mem_error_if(
            !Device_node_connect(dest_node, dest_port, src_node, src_port),
            rcdata->graph,
            NULL,
            sr);

    return true;
}
コード例 #7
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;
}
コード例 #8
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, ']');
}
コード例 #9
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, ']');
}