Logo Search packages:      
Sourcecode: alsa-tools version File versions  Download package

liblo10k1.c

/*
 *  EMU10k1 loader lib
 *  Copyright (c) 2003,2004 by Peter Zubaj
 *
 *
 *   This library is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as
 *   published by the Free Software Foundation; either version 2.1 of
 *   the License, or (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public
 *   License along with this library; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 */

#include <stdlib.h>
#include <string.h>
#include "comm.h"
#include "ld10k1_fnc.h"
#include "ld10k1_error.h"
#include "liblo10k1.h"
#include "liblo10k1ef.h"
#include "liblo10k1lf.h"
#include "ld10k1_debug.h"
#include "config.h"

int send_request_check(int conn_num, int op, void *data, int data_size)
{
      int opr, sizer;
      int err;

      if ((err = send_request(conn_num, op, data, data_size)) < 0)
            return err;

      if ((err = receive_response(conn_num, &opr, &sizer)) < 0)
            return err;
            
      return 0;
}

int send_msg_data_check(int conn_num, void *data, int data_size)
{
      int opr, sizer;
      int err;

      if ((err = send_msg_data(conn_num, data, data_size)) < 0)
            return err;

      if ((err = receive_response(conn_num, &opr, &sizer)) < 0)
            return err;
            
      return 0;
}

int receive_response_data_check(int conn_num, void *data, int idata_size)
{
      int err;
      int op, data_size;

      if ((err = receive_response(conn_num, &op, &data_size)) < 0)
            return err;
            
      if (op == FNC_ERR)
            return LD10K1_ERR_PROTOCOL;
      if (data_size != idata_size)
            return LD10K1_ERR_PROTOCOL;
            
      if ((err = receive_msg_data(conn_num, data, data_size)) < 0)
            return err;
            
      /* receive check */
      if ((err = receive_response(conn_num, &op, &data_size)) < 0)
            return err;
      
      return 0;
}

void liblo10k1_connection_init(liblo10k1_connection_t *conn)
{
      *conn = 0;
}

int liblo10k1_connect(liblo10k1_param *param, liblo10k1_connection_t *conn)
{
      int err;

      param->server = 0;
      *conn = setup_comm(param);
      if (*conn < 0)
            return LD10K1_ERR_COMM_CONN;
      if ((err = connect_comm(*conn, param)) < 0) {
            free_comm(*conn);
            *conn = 0;
            return err;
      }
      return 0;
}

int liblo10k1_disconnect(liblo10k1_connection_t *conn)
{
      send_request(*conn, FNC_CLOSE_CONN, NULL, 0);
      free_comm(*conn);
      *conn = 0;
      return 0;
}

int liblo10k1_is_open(liblo10k1_connection_t *conn)
{
      return *conn != 0;
}

int liblo10k1_patch_set_in_count(liblo10k1_dsp_patch_t *p, int count)
{
      liblo10k1_dsp_pio_t *tmp = NULL;
      
      if (count > 0) {
            tmp = (liblo10k1_dsp_pio_t *)malloc(sizeof(liblo10k1_dsp_pio_t) * count);
            if (!tmp)
                  return LD10K1_ERR_NO_MEM;
            memset(tmp, 0, sizeof(liblo10k1_dsp_pio_t) * count);
      }
      
      p->in_count = count;
      if (p->ins)
            free(p->ins);
      p->ins = tmp;
      return 0;
}

int liblo10k1_patch_set_out_count(liblo10k1_dsp_patch_t *p, int count)
{
      liblo10k1_dsp_pio_t *tmp = NULL;
      
      if (count > 0) {
            tmp = (liblo10k1_dsp_pio_t *)malloc(sizeof(liblo10k1_dsp_pio_t) * count);
            if (!tmp)
                  return LD10K1_ERR_NO_MEM;
            memset(tmp, 0, sizeof(liblo10k1_dsp_pio_t) * count);
      }
      
      p->out_count = count;
      if (p->outs)
            free(p->outs);
      p->outs = tmp;
      return 0;
}

int liblo10k1_patch_set_const_count(liblo10k1_dsp_patch_t *p, int count)
{
      liblo10k1_dsp_cs_t *tmp = NULL;
      
      if (count > 0) {
            tmp = (liblo10k1_dsp_cs_t *)malloc(sizeof(liblo10k1_dsp_cs_t) * count);
            if (!tmp)
                  return LD10K1_ERR_NO_MEM;
            memset(tmp, 0, sizeof(liblo10k1_dsp_cs_t) * count);
      }
      
      p->const_count = count;
      if (p->consts)
            free(p->consts);
      p->consts = tmp;
      return 0;
}

int liblo10k1_patch_set_sta_count(liblo10k1_dsp_patch_t *p, int count)
{
      liblo10k1_dsp_cs_t *tmp = NULL;
      
      if (count > 0) {
            tmp = (liblo10k1_dsp_cs_t *)malloc(sizeof(liblo10k1_dsp_cs_t) * count);
            if (!tmp)
                  return LD10K1_ERR_NO_MEM;
            memset(tmp, 0, sizeof(liblo10k1_dsp_cs_t) * count);
      }
      
      p->sta_count = count;
      if (p->stas)
            free(p->stas);
      p->stas = tmp;
      return 0;
}

int liblo10k1_patch_set_dyn_count(liblo10k1_dsp_patch_t *p, int count)
{
      p->dyn_count = count;
      return 0;
}

int liblo10k1_patch_set_hw_count(liblo10k1_dsp_patch_t *p, int count)
{
      liblo10k1_dsp_hw_t *tmp = NULL;
      
      if (count > 0) {
            tmp = (liblo10k1_dsp_hw_t *)malloc(sizeof(liblo10k1_dsp_hw_t) * count);
            if (!tmp)
                  return LD10K1_ERR_NO_MEM;
            memset(tmp, 0, sizeof(liblo10k1_dsp_hw_t) * count);
      }
      
      p->hw_count = count;
      if (p->hws)
            free(p->hws);
      p->hws = tmp;
      return 0;
}

int liblo10k1_patch_set_tram_count(liblo10k1_dsp_patch_t *p, int count)
{
      liblo10k1_dsp_tram_grp_t *tmp = NULL;
      
      if (count > 0) {
            tmp = (liblo10k1_dsp_tram_grp_t *)malloc(sizeof(liblo10k1_dsp_tram_grp_t) * count);
            if (!tmp)
                  return LD10K1_ERR_NO_MEM;
            memset(tmp, 0, sizeof(liblo10k1_dsp_tram_grp_t) * count);
      }
      
      p->tram_count = count;
      if (p->tram)
            free(p->tram);
      p->tram = tmp;
      return 0;
}

int liblo10k1_patch_set_tram_acc_count(liblo10k1_dsp_patch_t *p, int count)
{
      liblo10k1_dsp_tram_acc_t *tmp = NULL;
      
      if (count > 0) {
            tmp = (liblo10k1_dsp_tram_acc_t *)malloc(sizeof(liblo10k1_dsp_tram_acc_t) * count);
            if (!tmp)
                  return LD10K1_ERR_NO_MEM;
            memset(tmp, 0, sizeof(liblo10k1_dsp_tram_acc_t) * count);
      }
      
      p->tram_acc_count = count;
      if (p->tram_acc)
            free(p->tram_acc);
      p->tram_acc = tmp;
      return 0;
}

int liblo10k1_patch_set_ctl_count(liblo10k1_dsp_patch_t *p, int count)
{
      liblo10k1_dsp_ctl_t *tmp = NULL;
      
      if (count > 0) {
            tmp = (liblo10k1_dsp_ctl_t *)malloc(sizeof(liblo10k1_dsp_ctl_t) * count);
            if (!tmp)
                  return LD10K1_ERR_NO_MEM;
            memset(tmp, 0, sizeof(liblo10k1_dsp_ctl_t) * count);
      }
      
      p->ctl_count = count;
      if (p->ctl)
            free(p->ctl);
      p->ctl = tmp;
      return 0;
}

int liblo10k1_patch_set_instr_count(liblo10k1_dsp_patch_t *p, int count)
{
      liblo10k1_dsp_instr_t *tmp = NULL;
      
      if (count > 0) {
            tmp = (liblo10k1_dsp_instr_t *)malloc(sizeof(liblo10k1_dsp_instr_t) * count);
            if (!tmp)
                  return LD10K1_ERR_NO_MEM;
            memset(tmp, 0, sizeof(liblo10k1_dsp_instr_t) * count);
      }
      
      p->instr_count = count;
      if (p->instr)
            free(p->instr);
      p->instr = tmp;
      return 0;
}

liblo10k1_dsp_patch_t *liblo10k1_patch_alloc(int in_count, int out_count, int const_count, int sta_count, int dyn_count, int hw_count, int tram_count, int tram_acc_count, int ctl_count, int instr_count)
{
      liblo10k1_dsp_patch_t *np;
      int en = 0;

      np = (liblo10k1_dsp_patch_t *)malloc(sizeof(liblo10k1_dsp_patch_t));
      if (!np)
            return NULL;

      np->patch_name[0] ='\0';
      np->ins = NULL;
      np->outs = NULL;
      np->consts = NULL;
      np->stas = NULL;
      np->hws = NULL;
      np->tram = NULL;
      np->tram_acc = NULL;
      np->ctl = NULL;
      np->instr = NULL;

      if ((en = liblo10k1_patch_set_dyn_count(np, dyn_count)) < 0)
            goto error;
      if ((en = liblo10k1_patch_set_in_count(np, in_count)) < 0)
            goto error;
      if ((en = liblo10k1_patch_set_out_count(np, out_count)) < 0)
            goto error;
      if ((en = liblo10k1_patch_set_const_count(np, const_count)) < 0)
            goto error;
      if ((en = liblo10k1_patch_set_sta_count(np, sta_count)) < 0)
            goto error;
      if ((en = liblo10k1_patch_set_hw_count(np, hw_count)) < 0)
            goto error;
      if ((en = liblo10k1_patch_set_tram_count(np, tram_count)) < 0)
            goto error;
      if ((en = liblo10k1_patch_set_tram_acc_count(np, tram_acc_count)) < 0)
            goto error;
      if ((en = liblo10k1_patch_set_ctl_count(np, ctl_count)) < 0)
            goto error;
      if ((en = liblo10k1_patch_set_instr_count(np, instr_count)) < 0)
            goto error;
      return np;
error:
      liblo10k1_patch_free(np);
      return NULL;
}

void liblo10k1_patch_free(liblo10k1_dsp_patch_t *patch)
{
      liblo10k1_patch_set_in_count(patch, 0);
      liblo10k1_patch_set_out_count(patch, 0);
      liblo10k1_patch_set_const_count(patch, 0);
      liblo10k1_patch_set_dyn_count(patch, 0);
      liblo10k1_patch_set_sta_count(patch, 0);
      liblo10k1_patch_set_hw_count(patch, 0);
      liblo10k1_patch_set_tram_count(patch, 0);
      liblo10k1_patch_set_tram_acc_count(patch, 0);
      liblo10k1_patch_set_ctl_count(patch, 0);
      liblo10k1_patch_set_instr_count(patch, 0);
            
      free(patch);
}

int liblo10k1_patch_load(liblo10k1_connection_t *conn, liblo10k1_dsp_patch_t *patch, int before, int *loaded, int *loaded_id)
{
      int err;
      ld10k1_fnc_patch_add_t patch_fnc;
      int tmpres[2];

      strncpy(patch_fnc.patch.patch_name, patch->patch_name, sizeof(patch_fnc.patch.patch_name) - 1);
      patch_fnc.patch.patch_name[sizeof(patch_fnc.patch.patch_name) - 1] = '\0';
      
      patch_fnc.patch.in_count = patch->in_count;
      patch_fnc.patch.out_count = patch->out_count;
      patch_fnc.patch.const_count = patch->const_count;
      patch_fnc.patch.static_count = patch->sta_count;
      patch_fnc.patch.dynamic_count = patch->dyn_count;
      patch_fnc.patch.hw_count = patch->hw_count;
      patch_fnc.patch.tram_count = patch->tram_count;
      patch_fnc.patch.tram_acc_count = patch->tram_acc_count;
      patch_fnc.patch.ctl_count = patch->ctl_count;
      patch_fnc.patch.instr_count = patch->instr_count;

      /* patch */
      /* add */
      patch_fnc.where = before;
      if ((err = send_request_check(*conn, FNC_PATCH_ADD, &patch_fnc, sizeof(ld10k1_fnc_patch_add_t))) < 0)
            return err;

      /* in */
      if (patch->in_count)
            if ((err = send_msg_data_check(*conn, patch->ins, sizeof(ld10k1_dsp_p_in_out_t) * patch->in_count)) < 0)
                  return err;

      /* out */
      if (patch->out_count)
            if ((err = send_msg_data_check(*conn, patch->outs, sizeof(ld10k1_dsp_p_in_out_t) * patch->out_count)) < 0)
                  return err;

      /* const */
      if (patch->const_count)
            if ((err = send_msg_data_check(*conn, patch->consts, sizeof(ld10k1_dsp_p_const_static_t) * patch->const_count)) < 0)
                  return err;

      /* sta */
      if (patch->sta_count)
            if ((err = send_msg_data_check(*conn, patch->stas, sizeof(ld10k1_dsp_p_const_static_t) * patch->sta_count)) < 0)
                  return err;

      /* hw */
      if (patch->hw_count)
            if ((err = send_msg_data_check(*conn, patch->hws, sizeof(ld10k1_dsp_p_hw_t) * patch->hw_count)) < 0)
                  return err;

      if (patch->tram_count)
            /* tram groups */
            if ((err = send_msg_data_check(*conn, patch->tram, sizeof(ld10k1_dsp_tram_grp_t) * patch->tram_count)) < 0)
                  return err;

      if (patch->tram_acc_count)
            /* tram access */
            if ((err = send_msg_data_check(*conn, patch->tram_acc, sizeof(ld10k1_dsp_tram_acc_t) * patch->tram_acc_count)) < 0)
                  return err;

      if (patch->ctl_count)
            /* ctls */
            if ((err = send_msg_data_check(*conn, patch->ctl, sizeof(ld10k1_dsp_ctl_t) * patch->ctl_count)) < 0)
                  return err;

      /* instr */
      if ((err = send_msg_data_check(*conn, patch->instr, sizeof(ld10k1_dsp_instr_t) * patch->instr_count)) < 0)
            return err;

      if ((err = receive_response_data_check(*conn, tmpres, sizeof(tmpres))) < 0)
            return err;

      if (loaded)
            *loaded = tmpres[0];
      if (loaded_id)
            *loaded_id = tmpres[1];

      return 0;
}

int liblo10k1_debug(liblo10k1_connection_t *conn, int deb, void (*prn_fnc)(char *))
{
      int err;
      ld10k1_fnc_debug_t debug_info;
      char debug_line[1000];
      int opr, sizer;

      /* add */
      debug_info.what = deb;

      if ((err = send_request(*conn, FNC_DEBUG, &debug_info, sizeof(ld10k1_fnc_debug_t))) < 0)
            return err;

      while (1) {
            if ((err = receive_response(*conn, &opr, &sizer)) < 0)
                  return err;

            if (opr != FNC_CONTINUE)
                  break;

            if (sizer < (int)sizeof(debug_line)) {
                  if ((err = receive_msg_data(*conn, &debug_line, sizer)) < 0)
                        return err;
            } else
                  return LIBLO10K1_ERR_DEBUG;
            (*prn_fnc)(debug_line);
      }

      /* not checked */
      return receive_response(*conn, &opr, &sizer);
}

int liblo10k1_patch_unload(liblo10k1_connection_t *conn, int patch_num)
{
      ld10k1_fnc_patch_del_t patch_fnc;

      patch_fnc.where = patch_num;

      return send_request_check(*conn, FNC_PATCH_DEL, &patch_fnc, sizeof(ld10k1_fnc_patch_del_t));
}

int liblo10k1_dsp_init(liblo10k1_connection_t *conn)
{
      return send_request_check(*conn, FNC_DSP_INIT, NULL, 0);
}

static int liblo10k1_find_any(liblo10k1_connection_t *conn, int op, int patch, char *name, int *out)
{
      ld10k1_fnc_name_t name_info;
      int err;
      int idx = -1;

      name_info.patch_num = patch;
      name_info.gpr = -1;
      
      strncpy(name_info.name, name, sizeof(name_info.name) - 1);
      name_info.name[sizeof(name_info.name) - 1] = '\0';

      if ((err = send_request(*conn, op, &name_info, sizeof(ld10k1_fnc_name_t))) < 0)
            return err;

      if ((err = receive_response_data_check(*conn, &idx, sizeof(idx))) < 0)
            return err;
      
      *out = idx;
      return 0;
}

int liblo10k1_find_patch(liblo10k1_connection_t *conn, char *patch_name, int *out)
{
      return liblo10k1_find_any(conn, FNC_PATCH_FIND, -1, patch_name, out);
}

int liblo10k1_find_fx(liblo10k1_connection_t *conn, char *fx_name, int *out)
{
      return liblo10k1_find_any(conn, FNC_FX_FIND, -1, fx_name, out);
}

int liblo10k1_find_in(liblo10k1_connection_t *conn, char *in_name, int *out)
{
      return liblo10k1_find_any(conn, FNC_IN_FIND, -1, in_name, out);
}

int liblo10k1_find_out(liblo10k1_connection_t *conn, char *out_name, int *out)
{
      return liblo10k1_find_any(conn, FNC_OUT_FIND, -1, out_name, out);
}

int liblo10k1_find_patch_in(liblo10k1_connection_t *conn, int patch_num, char *patch_in_name, int *out)
{
      return liblo10k1_find_any(conn, FNC_PATCH_IN_FIND, patch_num, patch_in_name, out);
}

int liblo10k1_find_patch_out(liblo10k1_connection_t *conn, int patch_num, char *patch_out_name, int *out)
{
      return liblo10k1_find_any(conn, FNC_PATCH_OUT_FIND, patch_num, patch_out_name, out);
}

int liblo10k1_con_add(liblo10k1_connection_t *conn, int multi, int simple, int from_type, int from_patch, int from_io, int to_type, int to_patch, int to_io, int *ci)
{
      ld10k1_fnc_connection_t connection_fnc;
      int err;
      int conn_id;
      
      connection_fnc.what = FNC_CONNECTION_ADD;
      connection_fnc.multi = multi;
      connection_fnc.simple = simple;
      connection_fnc.from_type = from_type;
      connection_fnc.from_patch = from_patch;
      connection_fnc.from_io = from_io;
      connection_fnc.to_type = to_type;
      connection_fnc.to_patch = to_patch;
      connection_fnc.to_io = to_io;

      if ((err = send_request(*conn, FNC_CONNECTION_ADD, &connection_fnc, sizeof(ld10k1_fnc_connection_t))) < 0)
            return err;
      
      if ((err = receive_response_data_check(*conn, &conn_id, sizeof(conn_id))) < 0)
            return err;
            
      if (ci)
            *ci = conn_id;
      return 0;
}

int liblo10k1_con_del(liblo10k1_connection_t *conn, int type, int patch, int io, int *ci)
{
      ld10k1_fnc_connection_t connection_fnc;
      int err;
      int conn_id;

      connection_fnc.what = FNC_CONNECTION_DEL;
      connection_fnc.from_type = type;
      connection_fnc.from_patch = patch;
      connection_fnc.from_io = io;
      connection_fnc.to_type = -1;
      connection_fnc.to_patch = -1;
      connection_fnc.to_io = -1;
      
      if ((err = send_request(*conn, FNC_CONNECTION_DEL, &connection_fnc, sizeof(ld10k1_fnc_connection_t))) < 0)
            return err;
      
      if ((err = receive_response_data_check(*conn, &conn_id, sizeof(conn_id))) < 0)
            return err;
            
      if (ci)
            *ci = conn_id;
      return 0;
}

static int liblo10k1_rename_any(liblo10k1_connection_t *conn, int op, int patch_num, int gpr_num, char *name)
{
      ld10k1_fnc_name_t name_info;

      name_info.patch_num = patch_num;
      name_info.gpr = gpr_num;
      
      strncpy(name_info.name, name, sizeof(name_info.name) - 1);
      name_info.name[sizeof(name_info.name) - 1] = '\0';
      
      return send_request_check(*conn, op, &name_info, sizeof(ld10k1_fnc_name_t));
}

int liblo10k1_rename_patch(liblo10k1_connection_t *conn, int patch_num, char *patch_name)
{
      return liblo10k1_rename_any(conn, FNC_PATCH_RENAME, patch_num, -1, patch_name);
}

int liblo10k1_rename_patch_in(liblo10k1_connection_t *conn, int patch_num, int in, char *patch_in_name)
{
      return liblo10k1_rename_any(conn, FNC_PATCH_IN_RENAME, patch_num, in, patch_in_name);
}

int liblo10k1_rename_patch_out(liblo10k1_connection_t *conn, int patch_num, int out, char *patch_out_name)
{
      return liblo10k1_rename_any(conn, FNC_PATCH_OUT_RENAME, patch_num, out, patch_out_name);
}

int liblo10k1_rename_fx(liblo10k1_connection_t *conn, int fx, char *fx_name)
{
      return liblo10k1_rename_any(conn, FNC_FX_RENAME, -1, fx, fx_name);
}

int liblo10k1_rename_in(liblo10k1_connection_t *conn, int in, char *in_name)
{
      return liblo10k1_rename_any(conn, FNC_IN_RENAME, -1, in, in_name);
}

int liblo10k1_rename_out(liblo10k1_connection_t *conn, int out, char *out_name)
{
      return liblo10k1_rename_any(conn, FNC_OUT_RENAME, -1, out, out_name);
}

int liblo10k1_get_io(liblo10k1_connection_t *conn, int op, int io_num, liblo10k1_get_io_t *out);
int liblo10k1_get_pio(liblo10k1_connection_t *conn, int op, int patch_num, int io_num, liblo10k1_get_io_t *out);

int liblo10k1_get_fx(liblo10k1_connection_t *conn, int fx_num, liblo10k1_get_io_t *out)
{
      return liblo10k1_get_io(conn, FNC_GET_FX, fx_num, out);
}

int liblo10k1_get_in(liblo10k1_connection_t *conn, int in_num, liblo10k1_get_io_t *out)
{
      return liblo10k1_get_io(conn, FNC_GET_IN, in_num, out);
}

int liblo10k1_get_out(liblo10k1_connection_t *conn, int out_num, liblo10k1_get_io_t *out)
{
      return liblo10k1_get_io(conn, FNC_GET_OUT, out_num, out);
}

int liblo10k1_get_pin(liblo10k1_connection_t *conn, int patch_num, int in_num, liblo10k1_get_io_t *out)
{
      return liblo10k1_get_pio(conn, FNC_GET_PIN, patch_num, in_num, out);
}

int liblo10k1_get_pout(liblo10k1_connection_t *conn, int patch_num, int out_num, liblo10k1_get_io_t *out)
{
      return liblo10k1_get_pio(conn, FNC_GET_POUT, patch_num, out_num, out);
}

int liblo10k1_get_io(liblo10k1_connection_t *conn, int op, int io_num, liblo10k1_get_io_t *out)
{
      int err;
      
      if ((err = send_request(*conn, op, &io_num, sizeof(int))) < 0)
            return err;

      if ((err = receive_response_data_check(*conn, out, sizeof(liblo10k1_get_io_t))) < 0)
            return err;

      return 0;
}

int liblo10k1_get_pio(liblo10k1_connection_t *conn, int op, int patch_num, int io_num, liblo10k1_get_io_t *out)
{
      int tmp_num[2];
      int err;
      
      tmp_num[0] = patch_num;
      tmp_num[1] = io_num;
      
      if ((err = send_request(*conn, op, tmp_num, sizeof(int) * 2)) < 0)
            return err;

      if ((err = receive_response_data_check(*conn, out, sizeof(liblo10k1_get_io_t))) < 0)
            return err;
      
      return 0;
}

int liblo10k1_get_io_count(liblo10k1_connection_t *conn, int op, int *out);
int liblo10k1_get_pio_count(liblo10k1_connection_t *conn, int op, int patch_num, int *out);

int liblo10k1_get_fx_count(liblo10k1_connection_t *conn, int *out)
{
      return liblo10k1_get_io_count(conn, FNC_GET_FX_COUNT, out);
}

int liblo10k1_get_in_count(liblo10k1_connection_t *conn, int *out)
{
      return liblo10k1_get_io_count(conn, FNC_GET_IN_COUNT, out);
}

int liblo10k1_get_out_count(liblo10k1_connection_t *conn, int *out)
{
      return liblo10k1_get_io_count(conn, FNC_GET_OUT_COUNT, out);
}

int liblo10k1_get_pin_count(liblo10k1_connection_t *conn, int patch_num, int *out)
{
      return liblo10k1_get_pio_count(conn, FNC_GET_PIN_COUNT, patch_num, out);
}

int liblo10k1_get_pout_count(liblo10k1_connection_t *conn, int patch_num, int *out)
{
      return liblo10k1_get_pio_count(conn, FNC_GET_POUT_COUNT, patch_num, out);
}

int liblo10k1_get_io_count(liblo10k1_connection_t *conn, int op, int *out)
{
      int err;
      
      if ((err = send_request(*conn, op, 0, 0)) < 0)
            return err;

      if ((err = receive_response_data_check(*conn, out, sizeof(int))) < 0)
            return err;

      return 0;
}

int liblo10k1_get_pio_count(liblo10k1_connection_t *conn, int op, int patch_num, int *out)
{
      int err;
      
      if ((err = send_request(*conn, op, &patch_num, sizeof(int))) < 0)
            return err;

      if ((err = receive_response_data_check(*conn, out, sizeof(int))) < 0)
            return err;
      
      return 0;
}

int liblo10k1_get_patches_info(liblo10k1_connection_t *conn, liblo10k1_patches_info_t **out, int *count)
{
      liblo10k1_patches_info_t *info;
      int opr, sizer;
      int err;

      *out = NULL;
      *count = 0;
      info = NULL;

      if ((err = send_request(*conn, FNC_GET_PATCHES_INFO, 0, 0)) < 0)
            return err;

      if ((err = receive_response(*conn, &opr, &sizer)) < 0)
            return err;

      *count = sizer / sizeof(liblo10k1_patches_info_t);
      if (sizer > 0) {
            info = (liblo10k1_patches_info_t *)receive_msg_data_malloc(*conn, sizer);
            if (!info)
                  return LD10K1_ERR_NO_MEM;
      }

      if ((err = receive_response(*conn, &opr, &sizer)) < 0) {
            free(info);
            return err;
      }

      *out = info;
      return 0;
}

int liblo10k1_patch_get(liblo10k1_connection_t *conn, int patch_num, liblo10k1_dsp_patch_t **opatch)
{
      liblo10k1_dsp_patch_t *patch;
      int err;

      ld10k1_dsp_patch_t tmp_patch;
      int opr, sizer;


      if ((err = send_request(*conn, FNC_GET_PATCH, &patch_num, sizeof(patch_num))) < 0)
            return err;

      if ((err = receive_response(*conn, &opr, &sizer)) < 0)
            return err;

      if (opr != FNC_CONTINUE)
            return LD10K1_ERR_PROTOCOL;

      if ((err = receive_msg_data(*conn, &tmp_patch, sizeof(tmp_patch))) < 0)
            return err;

      /* alloc patch */
      patch = liblo10k1_patch_alloc(tmp_patch.in_count, tmp_patch.out_count, tmp_patch.const_count, tmp_patch.static_count, tmp_patch.dynamic_count, tmp_patch.hw_count, tmp_patch.tram_count, tmp_patch.tram_acc_count, tmp_patch.ctl_count, tmp_patch.instr_count);
      if (!patch)
            return LD10K1_ERR_NO_MEM;

      strcpy(patch->patch_name, tmp_patch.patch_name);

      /* ins */
      if (patch->in_count) {
            if ((err = receive_response(*conn, &opr, &sizer)) < 0)
                  return err;

            if (opr != FNC_CONTINUE || (unsigned int)sizer != patch->in_count * sizeof(ld10k1_dsp_p_in_out_t))
                  goto err_protocol;

            patch->ins = (ld10k1_dsp_p_in_out_t *)receive_msg_data_malloc(*conn, sizer);
            if (!patch->ins)
                  goto err_nomem;
      }

      /* outs */
      if (patch->out_count) {
            if ((err = receive_response(*conn, &opr, &sizer)) < 0)
                  return err;

            if (opr != FNC_CONTINUE || (unsigned int)sizer != patch->out_count * sizeof(ld10k1_dsp_p_in_out_t))
                  goto err_protocol;

            patch->outs = (ld10k1_dsp_p_in_out_t *)receive_msg_data_malloc(*conn, sizer);
            if (!patch->outs)
                  goto err_nomem;
      }

      /* consts */
      if (patch->const_count) {
            if ((err = receive_response(*conn, &opr, &sizer)) < 0)
                  return err;

            if (opr != FNC_CONTINUE || (unsigned int)sizer != patch->const_count * sizeof(ld10k1_dsp_p_const_static_t))
                  goto err_protocol;

            patch->consts = (ld10k1_dsp_p_const_static_t *)receive_msg_data_malloc(*conn, sizer);
            if (!patch->consts)
                  goto err_nomem;
      }

      /* stas */
      if (patch->sta_count) {
            if ((err = receive_response(*conn, &opr, &sizer)) < 0)
                  return err;

            if (opr != FNC_CONTINUE || (unsigned int)sizer != patch->sta_count * sizeof(ld10k1_dsp_p_const_static_t))
                  goto err_protocol;

            patch->stas = (ld10k1_dsp_p_const_static_t *)receive_msg_data_malloc(*conn, sizer);
            if (!patch->stas)
                  goto err_nomem;
      }

      /* hws */
      if (patch->hw_count) {
            if ((err = receive_response(*conn, &opr, &sizer)) < 0)
                  return err;

            if (opr != FNC_CONTINUE || (unsigned int)sizer != patch->hw_count * sizeof(ld10k1_dsp_p_hw_t))
                  goto err_protocol;

            patch->hws = (ld10k1_dsp_p_hw_t *)receive_msg_data_malloc(*conn, sizer);
            if (!patch->hws)
                  goto err_nomem;
      }

      /* tram grp */
      if (patch->tram_count) {
            if ((err = receive_response(*conn, &opr, &sizer)) < 0)
                  return err;

            if (opr != FNC_CONTINUE || (unsigned int)sizer != patch->tram_count * sizeof(liblo10k1_dsp_tram_grp_t))
                  goto err_protocol;

            patch->tram = (liblo10k1_dsp_tram_grp_t *)receive_msg_data_malloc(*conn, sizer);
            if (!patch->tram)
                  goto err_nomem;
      }

      /* tram acc */
      if (patch->tram_acc_count) {
            if ((err = receive_response(*conn, &opr, &sizer)) < 0)
                  return err;

            if (opr != FNC_CONTINUE || (unsigned int)sizer != patch->tram_acc_count * sizeof(liblo10k1_dsp_tram_acc_t))
                  goto err_protocol;

            patch->tram_acc = (liblo10k1_dsp_tram_acc_t *)receive_msg_data_malloc(*conn, sizer);
            if (!patch->tram_acc)
                  goto err_nomem;
      }

      /* ctls */
      if (patch->ctl_count) {
            if ((err = receive_response(*conn, &opr, &sizer)) < 0)
                  return err;

            if (opr != FNC_CONTINUE || (unsigned int)sizer != patch->ctl_count * sizeof(liblo10k1_dsp_ctl_t))
                  goto err_protocol;

            patch->ctl = (liblo10k1_dsp_ctl_t *)receive_msg_data_malloc(*conn, sizer);
            if (!patch->ctl)
                  goto err_nomem;
      }

      /* instr */
      if (patch->instr_count) {
            if ((err = receive_response(*conn, &opr, &sizer)) < 0)
                  return err;

            if (opr != FNC_CONTINUE || (unsigned int)sizer != patch->instr_count * sizeof(liblo10k1_dsp_instr_t))
                  goto err_protocol;

            patch->instr = (liblo10k1_dsp_instr_t *)receive_msg_data_malloc(*conn, sizer);
            if (!patch->instr)
                  goto err_nomem;
      }

      if ((err = receive_response(*conn, &opr, &sizer)) < 0) {
            liblo10k1_patch_free(patch);
            return err;
      }

      *opatch = patch;
      return 0;
err_nomem:
      liblo10k1_patch_free(patch);
      return LD10K1_ERR_NO_MEM;

err_protocol:
      liblo10k1_patch_free(patch);
      return LD10K1_ERR_PROTOCOL;
}

int liblo10k1_dump(liblo10k1_connection_t *conn, void **out, int *size)
{
      int opr, sizer;
      int err;
      void *dump = NULL;

      if ((err = send_request(*conn, FNC_DUMP, 0, 0)) < 0)
            return err;

      if ((err = receive_response(*conn, &opr, &sizer)) < 0)
            return err;

      *size = sizer;
      if (sizer > 0) {
            dump = receive_msg_data_malloc(*conn, sizer);
            if (!dump)
                  return LD10K1_ERR_NO_MEM;
      }

      if ((err = receive_response(*conn, &opr, &sizer)) < 0) {
            free(dump);
            return err;
      }

      *out = dump;
      return 0;
}

int liblo10k1_check_version(liblo10k1_connection_t *conn)
{
      int opr, sizer;
      int err;
      ld10k1_fnc_version_t ver;

      if ((err = send_request(*conn, FNC_VERSION, 0, 0)) < 0)
            return err;

      if ((err = receive_response(*conn, &opr, &sizer)) < 0)
            return err;

      if (sizer == sizeof(ver)) {
            if ((err = receive_msg_data(*conn, &ver, sizer)) < 0)
                  return err;
      }
      else
            return LD10K1_ERR_WRONG_VER;

      if ((err = receive_response(*conn, &opr, &sizer)) < 0)
            return err;

      if (strcmp(ver.ld10k1_version, VERSION) == 0)
            return 0;
      else
            return LD10K1_ERR_WRONG_VER;
}

int liblo10k1_get_points_info(liblo10k1_connection_t *conn, int **out, int *count)
{
      int *info;
      int opr, sizer;
      int err;

      info = NULL;

      if ((err = send_request(*conn, FNC_GET_POINTS_INFO, 0, 0)) < 0)
            return err;

      if ((err = receive_response(*conn, &opr, &sizer)) < 0)
            return err;

      *count = sizer / sizeof(int);
      if (sizer > 0) {
            info = (int *)receive_msg_data_malloc(*conn, sizer);
            if (!info)
                  return LD10K1_ERR_NO_MEM;
      }

      if ((err = receive_response(*conn, &opr, &sizer)) < 0) {
            free(info);
            return err;
      }

      *out = info;
      return 0;
}

int liblo10k1_get_point_info(liblo10k1_connection_t *conn, int point_id, liblo10k1_point_info_t *out)
{
      int opr, sizer;
      int err;

      if ((err = send_request(*conn, FNC_GET_POINT_INFO, &point_id, sizeof(point_id))) < 0)
            return err;

      if ((err = receive_response(*conn, &opr, &sizer)) < 0)
            return err;

      if (sizer != sizeof(liblo10k1_point_info_t))
            return LD10K1_ERR_PROTOCOL;
      if ((err = receive_msg_data(*conn, out, sizer)) < 0)
            return LD10K1_ERR_PROTOCOL;

      if ((err = receive_response(*conn, &opr, &sizer)) < 0)
            return err;

      return 0;
}

int liblo10k1_get_dsp_info(liblo10k1_connection_t *conn, liblo10k1_dsp_info_t *info)
{
      int err;
      
      if ((err = send_request(*conn, FNC_GET_DSP_INFO, NULL, 0)) < 0)
            return err;

      if ((err = receive_response_data_check(*conn, info, sizeof(liblo10k1_dsp_info_t))) < 0)
            return err;
      
      return 0;
}

struct errmsg_t
{
      int errnum;
      char *errmsg;
};

struct errmsg_t error_text[] =
{
      {LD10K1_ERR_UNKNOWN, "Unknown error"},
      {LD10K1_ERR_COMM_READ, "Error in read from socket"},
      {LD10K1_ERR_COMM_WRITE, "Error in write to socket"},
      {LD10K1_ERR_UNKNOWN_PATCH_NUM, "Wrong parameter - patch with this num doesn't exists"},
      {LD10K1_ERR_PROTOCOL, "ld10k1 is expecting more or less data as it got"},
      {LD10K1_ERR_COMM_CONN, "Error in socket connect"},

/* add patch */
      {LD10K1_ERR_PROTOCOL_IN_COUNT, "Wrong in registers count"},
      {LD10K1_ERR_PROTOCOL_OUT_COUNT, "Wrong out registers count"},
      {LD10K1_ERR_PROTOCOL_CONST_COUNT, "Wrong const registers count"},
      {LD10K1_ERR_PROTOCOL_STATIC_COUNT, "Wrong static registers count"},
      {LD10K1_ERR_PROTOCOL_DYNAMIC_COUNT, "Wrong dynamic registers count"},
      {LD10K1_ERR_PROTOCOL_HW_COUNT, "Wrong hw registers count"},
      {LD10K1_ERR_PROTOCOL_TRAM_COUNT, "Wrong tram count"},
      {LD10K1_ERR_PROTOCOL_TRAM_ACC_COUNT, "Wrong tram access registers count"},
      {LD10K1_ERR_PROTOCOL_CTL_COUNT, "Wrong controls count"},
      {LD10K1_ERR_PROTOCOL_INSTR_COUNT, "Wrong instructions count"},

/* driver */
      {LD10K1_ERR_DRIVER_CODE_POKE, "Unable to poke code"},
      {LD10K1_ERR_DRIVER_INFO, "Unable to get info"},
      {LD10K1_ERR_DRIVER_CODE_PEEK, "Unable to peek code"},
      {LD10K1_ERR_DRIVER_PCM_POKE, "Unable to poke pcm"},

/* tram */
      {LD10K1_ERR_ITRAM_FULL, "Not enought free itram"},
      {LD10K1_ERR_ETRAM_FULL, "Not enought free etram"},
      {LD10K1_ERR_TRAM_FULL, "Not enought free tram"},
      {LD10K1_ERR_TRAM_FULL_GRP, "Not enought free tram group"},

      {LD10K1_ERR_ITRAM_FULL_ACC, "Not enought free itram acc"},
      {LD10K1_ERR_ETRAM_FULL_ACC, "Not enought free etram acc"},
      {LD10K1_ERR_TRAM_FULL_ACC, "Not enought free tram acc"},

      {LD10K1_ERR_MAX_CON_PER_POINT, "Maximum connections per point reached"},

/* others */
      {LD10K1_ERR_NO_MEM, "Not enought free mem"},
      {LD10K1_ERR_MAX_PATCH_COUNT, "Max patch count excesed"},
      {LD10K1_ERR_NOT_FREE_REG, "There is not free reg"},
      {LD10K1_ERR_NOT_FREE_INSTR, "There is no free instruction slot"},

/* patch chceck */
      {LD10K1_ERR_WRONG_REG_HW_INDEX, "Loaded patch has wrong hw index"},
      {LD10K1_ERR_WRONG_TRAM_POS, "Loaded patch has wrong tram position"},

      {LD10K1_ERR_WRONG_TRAM_TYPE, "Loaded patch has wrong tram type"},
      {LD10K1_ERR_WRONG_TRAM_SIZE, "Loaded patch has wrong tram size"},
      {LD10K1_ERR_WRONG_TRAM_ACC_TYPE, "Loaded patch has wrong tram acc type"},

      {LD10K1_ERR_TRAM_GRP_OUT_OF_RANGE, "Loaded patch has tram gpr index out of range"},
      {LD10K1_ERR_TRAM_ACC_OUT_OF_RANGE, "Loaded patch has tram acc index out of range"},

      {LD10K1_ERR_CTL_VCOUNT_OUT_OF_RANGE, "Loaded patch has wrong count of visible gpr for control"},
      {LD10K1_ERR_CTL_COUNT_OUT_OF_RANGE, "Loaded patch has wrong count of gpr for control"},

      {LD10K1_ERR_CTL_MIN_MAX_RANGE, "Loaded patch has wrong min, max range for control"},
      {LD10K1_ERR_CTL_TRANLSLATION, "Loaded patch has wrong translation function for control"},
      {LD10K1_ERR_CTL_REG_INDEX, "Loaded patch has wrong gpr index for control"},
      {LD10K1_ERR_CTL_REG_VALUE, "Loaded patch has wrong initial value for control"},

      {LD10K1_ERR_INSTR_OPCODE, "Loaded patch has wrong instruction opcode"},
      {LD10K1_ERR_INSTR_ARG_INDEX, "Loaded patch has wrong argument for instruction"},

      {LD10K1_ERR_UNKNOWN_REG_NUM, "There isn't register with this reg number"},
      {LD10K1_ERR_UNKNOWN_PATCH_REG_NUM, "There isn't patch register with this reg number for patch"},

      {LD10K1_ERR_CONNECTION, "Couldn't connect patch to io"},
      {LD10K1_ERR_CONNECTION_FNC, "Not supported connect/disconnect function"},

      {LD10K1_ERR_CTL_EXISTS, "Can't add control because there is one with same name"},

      {LD10K1_ERR_PATCH_RENAME, "Couldn't rename patch"},
      {LD10K1_ERR_PATCH_REG_RENAME, "Couldn't rename patch register"},
      {LD10K1_ERR_REG_RENAME, "Couldn't rename register"},
      {LD10K1_ERR_WRONG_VER, "Wrong ld10k1 version"},
      {LD10K1_ERR_UNKNOWN_POINT, "Unknown point"},
      
      /* errors from liblo10k1ef */
      {LD10K1_EF_ERR_OPEN, "Can not open file"},
      {LD10K1_EF_ERR_STAT, "Can not stat file"},
      {LD10K1_EF_ERR_SIZE, "Wrong file size"},
      {LD10K1_EF_ERR_READ, "Can not read file"},
      {LD10K1_EF_ERR_SIGNATURE, "Wrong file signature"},
      {LD10K1_EF_ERR_FORMAT, "Wrong file format"},

      {LD10K1_EF_ERR_TRANSFORM_CTL, "Can not transform control"},
      {LD10K1_EF_ERR_TRANSFORM, "Can not transform effect"},
      {LD10K1_EF_ERR_TRANSFORM_TRANS, "Wrong control translation"},
      
      /* errors from liblo10k1lf */
      {LD10K1_LF_ERR_OPEN, "Can not open file"},
      {LD10K1_LF_ERR_WRITE, "Can not write file"},
      {LD10K1_LF_ERR_READ, "Can not read file"},
      {LD10K1_LF_ERR_SIGNATURE, "Wrong file signature"},
      {LD10K1_LF_ERR_PART_TYPE, "Wrong part type"},
      {LD10K1_LF_ERR_PART_SIZE, "Wrong part size"},
      {LD10K1_LF_ERR_VERSION, "Wrong file version"},
      {LD10K1_LF_ERR_FILE_TYPE, "Wrong file type"},

      {0, ""}
};

char *liblo10k1_error_str(int error)
{
      int i;

      for (i = 0; error_text[i].errnum != 0; i++)
            if (error_text[i].errnum == error)
                  return error_text[i].errmsg;
      return "Error msg not specified in liblo10k1";
}

Generated by  Doxygen 1.6.0   Back to index