/* * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "version.h" #include "ld10k1.h" #include "ld10k1_fnc.h" #include "ld10k1_error.h" #include "comm.h" #include "liblo10k1.h" #include "liblo10k1lf.h" #define CREATER_MAJOR LD10K1_LIB_MAJOR #define CREATER_MINOR LD10K1_LIB_MINOR #define CREATER_SUBMINOR LD10K1_LIB_SUBMINOR #define FILE_MAJOR 0 #define FILE_MINOR 1 #define FILE_SUBMINOR 0 #define READER_MAJOR 0 #define READER_MINOR 1 #define READER_SUBMINOR 7 #define LD10K1_FILE_SIGNATURE "LD10K1 NATIVE EFFECT FILE " int liblo10k1lf_save_dsp_setup(liblo10k1_file_dsp_setup_t *c, FILE *file); int liblo10k1lf_save_file_header(FILE *file, unsigned int ft); int liblo10k1lf_save_file_info(FILE *file, liblo10k1_file_info_t *fi); int liblo10k1lf_save_part(FILE *file, unsigned int part_type, unsigned int part_id, unsigned int part_length, void *data); int liblo10k1lf_find_part(FILE *file, unsigned int part_type, unsigned int part_id, unsigned int part_length, liblo10k1_file_part_t *part); int liblo10k1lf_find_part_il(FILE *file, unsigned int part_type, unsigned int part_id, unsigned int part_length, int il, liblo10k1_file_part_t *part); int liblo10k1lf_save_dsp_config(liblo10k1_file_dsp_setup_t *c, char *file_name, liblo10k1_file_info_t *fi) { FILE *file = NULL; int err; file = fopen(file_name, "w"); if (!file) return LD10K1_LF_ERR_OPEN; if ((err = liblo10k1lf_save_file_header(file, LD10K1_FP_INFO_FILE_TYPE_DSP_SETUP)) < 0) goto err; if ((err = liblo10k1lf_save_file_info(file, fi)) < 0) goto err; if ((err = liblo10k1lf_save_dsp_setup(c, file)) < 0) goto err; fclose(file); return 0; err: fclose(file); return err; } int liblo10k1lf_save_part(FILE *file, unsigned int part_type, unsigned int part_id, unsigned int part_length, void *data) { liblo10k1_file_part_t part; memset(&part, 0, sizeof(part)); part.part_type = part_type; part.part_id = part_id; part.part_length = part_length; if (fwrite(&part, sizeof(liblo10k1_file_part_t), 1, file) != 1) return LD10K1_LF_ERR_WRITE; if (part_length > 0) if (fwrite(data, part_length, 1, file) != 1) return LD10K1_LF_ERR_WRITE; return 0; } int liblo10k1lf_save_file_header(FILE *file, unsigned int ft) { liblo10k1_file_header_t fhdr; liblo10k1_file_part_info_t file_info; int err; strcpy(fhdr.signature, LD10K1_FILE_SIGNATURE); memset(fhdr.reserved, 0, sizeof(fhdr.reserved)); if (fwrite(&fhdr, sizeof(liblo10k1_file_header_t), 1, file) != 1) return LD10K1_LF_ERR_WRITE; memset(&file_info, 0, sizeof(file_info)); file_info.file_type = ft; file_info.file_version_major = FILE_MAJOR; file_info.file_version_minor = FILE_MINOR; file_info.file_version_subminor = FILE_SUBMINOR; /* file version = 0.0.1 */ file_info.minimal_reader_version_major = READER_MAJOR; file_info.minimal_reader_version_minor = READER_MINOR; file_info.minimal_reader_version_subminor = READER_SUBMINOR; /* minimal reader version = 0.1.7 */ file_info.creater_version_major = CREATER_MAJOR; file_info.creater_version_minor = CREATER_MINOR; file_info.creater_version_subminor = CREATER_SUBMINOR; /* creater version = 0.1.7 */ if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_NORMAL, LD10K1_FP_INFO, sizeof(file_info), &file_info)) < 0) return err; return 0; } int liblo10k1lf_save_string_info(FILE *file, int id, char *str) { int str_len; int err; if (str) str_len = strlen(str) + 1; else str_len = 0; if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_NORMAL, id, str_len, str)) < 0) return err; return 0; } int liblo10k1lf_load_string_info(FILE *file, int id, char **str) { char *tmp; int err; liblo10k1_file_part_t part; if ((err = liblo10k1lf_find_part_il(file, LD10K1_FP_TYPE_NORMAL, id, 0, 1, &part)) < 0) return err; tmp = NULL; if (part.part_length > 0) { tmp = (char *)malloc(part.part_length); if (!tmp) return LD10K1_ERR_NO_MEM; if (fread(tmp, part.part_length, 1, file) != 1) { free(tmp); return LD10K1_LF_ERR_READ; } } if (*str) free(*str); *str = tmp; return 0; } int liblo10k1lf_save_file_info(FILE *file, liblo10k1_file_info_t *fi) { int err; if ((err = liblo10k1lf_save_string_info(file, LD10K1_FP_FILE_INFO_NAME, fi->name)) < 0) return err; if ((err = liblo10k1lf_save_string_info(file, LD10K1_FP_FILE_INFO_DESC, fi->desc)) < 0) return err; if ((err = liblo10k1lf_save_string_info(file, LD10K1_FP_FILE_INFO_CREATER, fi->creater)) < 0) return err; if ((err = liblo10k1lf_save_string_info(file, LD10K1_FP_FILE_INFO_AUTHOR, fi->author)) < 0) return err; if ((err = liblo10k1lf_save_string_info(file, LD10K1_FP_FILE_INFO_COPYRIGHT, fi->copyright)) < 0) return err; if ((err = liblo10k1lf_save_string_info(file, LD10K1_FP_FILE_INFO_LICENCE, fi->license)) < 0) return err; return 0; } int liblo10k1lf_load_file_info(FILE *file, liblo10k1_file_info_t **fi) { int err; liblo10k1_file_info_t *i = liblo10k1lf_file_info_alloc(); if (!i) return LD10K1_ERR_NO_MEM; if ((err = liblo10k1lf_load_string_info(file, LD10K1_FP_FILE_INFO_NAME, &(i->name))) < 0) goto err; if ((err = liblo10k1lf_load_string_info(file, LD10K1_FP_FILE_INFO_DESC, &(i->desc))) < 0) goto err; if ((err = liblo10k1lf_load_string_info(file, LD10K1_FP_FILE_INFO_CREATER, &(i->creater))) < 0) goto err; if ((err = liblo10k1lf_load_string_info(file, LD10K1_FP_FILE_INFO_AUTHOR, &(i->author))) < 0) goto err; if ((err = liblo10k1lf_load_string_info(file, LD10K1_FP_FILE_INFO_COPYRIGHT, &(i->copyright))) < 0) goto err; if ((err = liblo10k1lf_load_string_info(file, LD10K1_FP_FILE_INFO_LICENCE, &(i->license))) < 0) goto err; *fi = i; return 0; err: if (i) liblo10k1lf_file_info_free(i); return err; } int liblo10k1lf_save_io(liblo10k1_get_io_t *ios, int count, int ptl, int pt, FILE *file) { int i, err; /* io list start */ if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_START, ptl, 0, NULL)) < 0) return err; for (i = 0; i < count; i++) { if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_NORMAL, pt, sizeof(liblo10k1_get_io_t), &(ios[i]))) < 0) return err; } if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_END, ptl, 0, NULL)) < 0) return err; return 0; } int liblo10k1lf_save_pio(liblo10k1_dsp_pio_t *ios, int count, int ptl, int pt, FILE *file) { int i, err; /* io list start */ if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_START, ptl, 0, NULL)) < 0) return err; for (i = 0; i < count; i++) { if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_NORMAL, pt, sizeof(liblo10k1_dsp_pio_t), &(ios[i]))) < 0) return err; } if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_END, ptl, 0, NULL)) < 0) return err; return 0; } int liblo10k1lf_save_cs(liblo10k1_dsp_cs_t *css, int count, int ptl, int pt, FILE *file) { int i, err; /* io list start */ if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_START, ptl, 0, NULL)) < 0) return err; for (i = 0; i < count; i++) { if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_NORMAL, pt, sizeof(liblo10k1_dsp_cs_t), &(css[i]))) < 0) return err; } if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_END, ptl, 0, NULL)) < 0) return err; return 0; } int liblo10k1lf_save_hw(liblo10k1_dsp_hw_t *hws, int count, FILE *file) { int i, err; /* io list start */ if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_START, LD10K1_FP_HW_LIST, 0, NULL)) < 0) return err; for (i = 0; i < count; i++) { if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_NORMAL, LD10K1_FP_HW, sizeof(liblo10k1_dsp_hw_t), &(hws[i]))) < 0) return err; } if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_END, LD10K1_FP_HW_LIST, 0, NULL)) < 0) return err; return 0; } int liblo10k1lf_save_tram(liblo10k1_dsp_tram_grp_t *trams, int count, FILE *file) { int i, err; /* io list start */ if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_START, LD10K1_FP_TRAM_LIST, 0, NULL)) < 0) return err; for (i = 0; i < count; i++) { if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_NORMAL, LD10K1_FP_TRAM, sizeof(liblo10k1_dsp_tram_grp_t), &(trams[i]))) < 0) return err; } if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_END, LD10K1_FP_TRAM_LIST, 0, NULL)) < 0) return err; return 0; } int liblo10k1lf_save_tram_acc(liblo10k1_dsp_tram_acc_t *tram_accs, int count, FILE *file) { int i, err; /* io list start */ if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_START, LD10K1_FP_TRAM_ACC_LIST, 0, NULL)) < 0) return err; for (i = 0; i < count; i++) { if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_NORMAL, LD10K1_FP_TRAM_ACC, sizeof(liblo10k1_dsp_tram_acc_t), &(tram_accs[i]))) < 0) return err; } if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_END, LD10K1_FP_TRAM_ACC_LIST, 0, NULL)) < 0) return err; return 0; } int liblo10k1lf_save_ctl(liblo10k1_dsp_ctl_t *ctls, int count, FILE *file) { int i, err; /* io list start */ if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_START, LD10K1_FP_CTL_LIST, 0, NULL)) < 0) return err; for (i = 0; i < count; i++) { if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_NORMAL, LD10K1_FP_CTL, sizeof(liblo10k1_dsp_ctl_t), &(ctls[i]))) < 0) return err; } if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_END, LD10K1_FP_CTL_LIST, 0, NULL)) < 0) return err; return 0; } int liblo10k1lf_save_instr(liblo10k1_dsp_instr_t *instrs, int count, FILE *file) { int i, err; /* io list start */ if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_START, LD10K1_FP_INSTR_LIST, 0, NULL)) < 0) return err; for (i = 0; i < count; i++) { if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_NORMAL, LD10K1_FP_INSTR, sizeof(liblo10k1_dsp_instr_t), &(instrs[i]))) < 0) return err; } if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_END, LD10K1_FP_INSTR_LIST, 0, NULL)) < 0) return err; return 0; } int liblo10k1lf_save_points(liblo10k1_point_info_t *points, int count, FILE *file) { int i, err; /* io list start */ if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_START, LD10K1_FP_POINT_LIST, 0, NULL)) < 0) return err; for (i = 0; i < count; i++) { if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_NORMAL, LD10K1_FP_POINT, sizeof(liblo10k1_point_info_t), &(points[i]))) < 0) return err; } if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_END, LD10K1_FP_POINT_LIST, 0, NULL)) < 0) return err; return 0; } int liblo10k1lf_save_patch(liblo10k1_dsp_patch_t *p, FILE *file) { int err; liblo10k1_file_patch_info_t pinfo; /* io list start */ if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_START, LD10K1_FP_PATCH, 0, NULL)) < 0) return err; /* patch info */ strcpy(pinfo.patch_name, p->patch_name); pinfo.in_count = p->in_count; pinfo.out_count = p->out_count; pinfo.const_count = p->const_count; pinfo.sta_count = p->sta_count; pinfo.dyn_count = p->dyn_count; pinfo.hw_count = p->hw_count; pinfo.tram_count = p->tram_count; pinfo.tram_acc_count = p->tram_acc_count; pinfo.ctl_count = p->ctl_count; pinfo.instr_count = p->instr_count; if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_NORMAL, LD10K1_FP_PATCH_INFO, sizeof(liblo10k1_file_patch_info_t), &pinfo)) < 0) return err; /* pins */ if ((err = liblo10k1lf_save_pio(p->ins, p->in_count, LD10K1_FP_PIN_LIST, LD10K1_FP_PIO, file)) < 0) return err; /* pouts */ if ((err = liblo10k1lf_save_pio(p->outs, p->out_count, LD10K1_FP_POUT_LIST, LD10K1_FP_PIO, file)) < 0) return err; /* consts */ if ((err = liblo10k1lf_save_cs(p->consts, p->const_count, LD10K1_FP_CONST_LIST, LD10K1_FP_CS, file)) < 0) return err; /* stas */ if ((err = liblo10k1lf_save_cs(p->stas, p->sta_count, LD10K1_FP_STA_LIST, LD10K1_FP_CS, file)) < 0) return err; /* hws */ if ((err = liblo10k1lf_save_hw(p->hws, p->hw_count, file)) < 0) return err; /* trams */ if ((err = liblo10k1lf_save_tram(p->tram, p->tram_count, file)) < 0) return err; /* tram_accs */ if ((err = liblo10k1lf_save_tram_acc(p->tram_acc, p->tram_acc_count, file)) < 0) return err; /* ctls */ if ((err = liblo10k1lf_save_ctl(p->ctl, p->ctl_count, file)) < 0) return err; /* instrs */ if ((err = liblo10k1lf_save_instr(p->instr, p->instr_count, file)) < 0) return err; if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_END, LD10K1_FP_PATCH, 0, NULL)) < 0) return err; return 0; } int liblo10k1lf_save_dsp_setup(liblo10k1_file_dsp_setup_t *c, FILE *file) { liblo10k1_file_part_dsp_setup_t setup; int err; int i; setup.dsp_type = c->dsp_type; setup.fx_count = c->fx_count; setup.in_count = c->in_count; setup.out_count = c->out_count; setup.patch_count = c->patch_count; setup.point_count = c->point_count; if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_NORMAL, LD10K1_FP_DSP_SETUP, sizeof(setup), &setup)) < 0) return err; /* save fx */ if ((err = liblo10k1lf_save_io(c->fxs, c->fx_count, LD10K1_FP_FX_LIST, LD10K1_FP_FX, file)) < 0) return err; /* save in */ if ((err = liblo10k1lf_save_io(c->ins, c->in_count, LD10K1_FP_IN_LIST, LD10K1_FP_IN, file)) < 0) return err; /* save out */ if ((err = liblo10k1lf_save_io(c->outs, c->out_count, LD10K1_FP_OUT_LIST, LD10K1_FP_OUT, file)) < 0) return err; /* save patches */ if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_START, LD10K1_FP_PATCH_LIST, 0, NULL)) < 0) return err; for (i = 0; i < c->patch_count; i++) { if ((err = liblo10k1lf_save_patch(c->patches[i], file)) < 0) return err; } if ((err = liblo10k1lf_save_part(file, LD10K1_FP_TYPE_END, LD10K1_FP_PATCH_LIST, 0, NULL)) < 0) return err; /* save points */ if ((err = liblo10k1lf_save_points(c->points, c->point_count, file)) < 0) return err; return 0; } liblo10k1_file_dsp_setup_t *liblo10k1lf_dsp_config_alloc() { liblo10k1_file_dsp_setup_t *tmp = (liblo10k1_file_dsp_setup_t *)malloc(sizeof(liblo10k1_file_dsp_setup_t)); memset(tmp, 0, sizeof(liblo10k1_file_dsp_setup_t)); return tmp; } void liblo10k1lf_dsp_config_free(liblo10k1_file_dsp_setup_t *c) { int i; if (c->fxs) free(c->fxs); if (c->ins) free(c->ins); if (c->outs) free(c->outs); if (c->patches) { for (i = 0; i < c->patch_count; i++) { if (c->patches[i]) liblo10k1_patch_free(c->patches[i]); } free(c->patches); } if (c->points) free(c->points); } int liblo10k1lf_dsp_config_set_fx_count(liblo10k1_file_dsp_setup_t *c, int count) { liblo10k1_get_io_t *tmp = NULL; if (count > 0) { tmp = (liblo10k1_get_io_t *)malloc(sizeof(liblo10k1_get_io_t) * count); if (!tmp) return LD10K1_ERR_NO_MEM; } if (c->fxs) free(c->fxs); c->fx_count = count; c->fxs = tmp; return 0; } int liblo10k1lf_dsp_config_set_in_count(liblo10k1_file_dsp_setup_t *c, int count) { liblo10k1_get_io_t *tmp = NULL; if (count > 0) { tmp = (liblo10k1_get_io_t *)malloc(sizeof(liblo10k1_get_io_t) * count); if (!tmp) return LD10K1_ERR_NO_MEM; } if (c->ins) free(c->ins); c->in_count = count; c->ins = tmp; return 0; } int liblo10k1lf_dsp_config_set_out_count(liblo10k1_file_dsp_setup_t *c, int count) { liblo10k1_get_io_t *tmp = NULL; if (count > 0) { tmp = (liblo10k1_get_io_t *)malloc(sizeof(liblo10k1_get_io_t) * count); if (!tmp) return LD10K1_ERR_NO_MEM; } if (c->outs) free(c->outs); c->out_count = count; c->outs = tmp; return 0; } int liblo10k1lf_dsp_config_set_patch_count(liblo10k1_file_dsp_setup_t *c, int count) { int i; /* alloc patches list */ liblo10k1_dsp_patch_t **tmp = NULL; if (count > 0) { tmp = (liblo10k1_dsp_patch_t **)malloc(sizeof(liblo10k1_dsp_patch_t *) * count); if (!tmp) return LD10K1_ERR_NO_MEM; memset(tmp, 0, sizeof(liblo10k1_dsp_patch_t *) * count); } if (c->patches) { for (i = 0; i < c->patch_count; i++) { if (c->patches[i]) liblo10k1_patch_free(c->patches[i]); } free(c->patches); } c->patch_count = count; c->patches = tmp; return 0; } int liblo10k1lf_dsp_config_set_point_count(liblo10k1_file_dsp_setup_t *c, int count) { liblo10k1_point_info_t *tmp = NULL; if (count > 0) { tmp = (liblo10k1_point_info_t *)malloc(sizeof(liblo10k1_point_info_t) * count); if (!tmp) return LD10K1_ERR_NO_MEM; memset(tmp, 0, sizeof(liblo10k1_point_info_t) * count); } if (c->points) free(c->points); c->point_count = count; c->points = tmp; return 0; } int liblo10k1lf_get_dsp_config(liblo10k1_connection_t *conn, liblo10k1_file_dsp_setup_t **setup) { liblo10k1_dsp_info_t info; int err; int i, j, k; liblo10k1_file_dsp_setup_t *s; liblo10k1_patches_info_t *plist; int pcount; int tmp; int *points; plist = NULL; points = NULL; s = liblo10k1lf_dsp_config_alloc(); if (!s) return LD10K1_ERR_NO_MEM; /* get dsp type */ if ((err = liblo10k1_get_dsp_info(conn, &info)) < 0) return err; s->dsp_type = LD10K1_FP_INFO_DSP_TYPE_EMU10K1; if (info.chip_type == CHIP_LIVE) s->dsp_type = LD10K1_FP_INFO_DSP_TYPE_EMU10K1; else if (info.chip_type == CHIP_AUDIGY) s->dsp_type = LD10K1_FP_INFO_DSP_TYPE_EMU10K2; /* now get everything what is needed */ if ((err = liblo10k1_get_fx_count(conn, &tmp)) < 0) goto err; if ((err = liblo10k1lf_dsp_config_set_fx_count(s, tmp)) < 0) goto err; for (i = 0; i < s->fx_count; i++) { if ((err = liblo10k1_get_fx(conn, i, &(s->fxs[i]))) < 0) goto err; } if ((err = liblo10k1_get_in_count(conn, &tmp)) < 0) goto err; if ((err = liblo10k1lf_dsp_config_set_in_count(s, tmp)) < 0) goto err; for (i = 0; i < s->in_count; i++) { if ((err = liblo10k1_get_in(conn, i, &(s->ins[i]))) < 0) goto err; } if ((err = liblo10k1_get_out_count(conn, &tmp)) < 0) goto err; if ((err = liblo10k1lf_dsp_config_set_out_count(s, tmp)) < 0) goto err; for (i = 0; i < s->out_count; i++) { if ((err = liblo10k1_get_out(conn, i, &(s->outs[i]))) < 0) goto err; } if ((err = liblo10k1_get_patches_info(conn, &plist, &pcount)) < 0) goto err; /* alloc patches list */ if ((err = liblo10k1lf_dsp_config_set_patch_count(s, pcount)) < 0) goto err; for (i = 0; i < s->patch_count; i++) { if ((err = liblo10k1_patch_get(conn, plist[i].patch_num, &(s->patches[i]))) < 0) goto err; } if ((err = liblo10k1_get_points_info(conn, &points, &pcount)) < 0) goto err; if ((err = liblo10k1lf_dsp_config_set_point_count(s, pcount)) < 0) goto err; for (i = 0; i < s->point_count; i++) { if ((err = liblo10k1_get_point_info(conn, points[i], &(s->points[i]))) < 0) goto err; /* id to patch index */ for (j = 0; j < s->points[i].conn_count;j++) { if (s->points[i].patch[j] >= 0) { for (k = 0; k < s->patch_count; k++) { if (plist[k].id == s->points[i].patch[j]) { s->points[i].patch[j] = k; break; } } if (s->points[i].patch[j] != k) { err = LD10K1_ERR_UNKNOWN_PATCH_NUM; goto err; } } } } free(plist); free(points); *setup = s; return 0; err: if (plist) free(plist); if (points) free(points); liblo10k1lf_dsp_config_free(s); return err; } int liblo10k1lf_put_dsp_config(liblo10k1_connection_t *conn, liblo10k1_file_dsp_setup_t *setup) { int err; int i, j; int loaded_id; int loaded; int *trans_nums; int tin_type, tout_type; int tin, tout; int tpin, tpout; int pnum; tin_type = 0; tout_type = 0; tin = 0; tout = 0; tpin = 0; tpout = 0; /* first initialize dsp */ if ((err = liblo10k1_dsp_init(conn)) < 0) return err; for (i = 0; i < setup->fx_count; i++) { if ((err = liblo10k1_rename_fx(conn, i, setup->fxs[i].name)) < 0) return err; } for (i = 0; i < setup->in_count; i++) { if ((err = liblo10k1_rename_in(conn, i, setup->ins[i].name)) < 0) return err; } for (i = 0; i < setup->out_count; i++) { if ((err = liblo10k1_rename_out(conn, i, setup->outs[i].name)) < 0) return err; } if (setup->patch_count <= 0) return 0; trans_nums = (int *)malloc(sizeof(int) * setup->patch_count); if (!trans_nums) return LD10K1_ERR_NO_MEM; memset(trans_nums, 0, sizeof(int) * setup->patch_count); /* load all patches - remember ids */ for (i = 0; i < setup->patch_count; i++) { if ((err = liblo10k1_patch_load(conn, setup->patches[i], -1, &loaded, &loaded_id)) < 0) goto err; trans_nums[i] = loaded; } /* connect all connections */ for (i = 0; i < setup->point_count; i++) { if (setup->points[i].type == CON_IO_NORMAL) { /* find first pin */ for (j = 0; j < setup->points[i].conn_count;j++) if (!setup->points[i].io_type[j]) { tin_type = CON_IO_PIN; tin = setup->points[i].io[j]; tpin = setup->points[i].patch[j]; if (tpin >= 0) tpin = trans_nums[tpin]; break; } /* find first pout */ for (j = 0; j < setup->points[i].conn_count;j++) if (setup->points[i].io_type[j]) { tout_type = CON_IO_POUT; tout = setup->points[i].io[j]; tpout = setup->points[i].patch[j]; if (tpout >= 0) tpout = trans_nums[tpout]; break; } for (j = 0; j < setup->points[i].conn_count; j++) { pnum = setup->points[i].patch[j]; if (pnum >= 0) pnum = trans_nums[pnum]; if (!setup->points[i].io_type[j]) { if ((err = liblo10k1_con_add(conn, j == 0 ? 0 : setup->points[i].multi, setup->points[i].simple, CON_IO_PIN, pnum, setup->points[i].io[j], tout_type, tpout, tout, NULL)) < 0) goto err; } else { if ((err = liblo10k1_con_add(conn, j == 0 ? 0 : setup->points[i].multi, setup->points[i].simple, CON_IO_POUT, pnum, setup->points[i].io[j], tin_type, tpin, tin, NULL)) < 0) goto err; } } } else { tin_type = tout_type = setup->points[i].type; tin = tout = setup->points[i].io_idx; tpin = tpout = -1; for (j = 0; j < setup->points[i].conn_count; j++) { pnum = setup->points[i].patch[j]; if (pnum >= 0) pnum = trans_nums[pnum]; if ((err = liblo10k1_con_add(conn, j == 0 ? 0 : setup->points[i].multi, setup->points[i].simple, setup->points[i].io_type[j] ? CON_IO_POUT : CON_IO_PIN, pnum, setup->points[i].io[j], tin_type, tpin, tin, NULL)) < 0) goto err; } } } return 0; err: if (trans_nums) free(trans_nums); return err; } int liblo10k1lf_skip_part(FILE *file, liblo10k1_file_part_t *part) { char tmp_char; int i; int err; int found_end_part = 0; if (part->part_type == LD10K1_FP_TYPE_NORMAL) { /* read all data */ for (i = 0; i < part->part_length; i++) if (fread(&tmp_char, 1, 1, file) != 1) return LD10K1_LF_ERR_READ; } else if (part->part_type == LD10K1_FP_TYPE_END) { return 0; } else { while (!found_end_part) { /* read next part */ if (fread(part, sizeof(liblo10k1_file_part_t), 1, file) != 1) return LD10K1_LF_ERR_READ; /* check type & id */ if (part->part_type == LD10K1_FP_TYPE_END) found_end_part = 1; else { if ((err = liblo10k1lf_skip_part(file, part)) < 0) return err; } } } return 0; } int liblo10k1lf_find_part_il(FILE *file, unsigned int part_type, unsigned int part_id, unsigned int part_length, int il, liblo10k1_file_part_t *part) { int err; while (1) { if (fread(part, sizeof(liblo10k1_file_part_t), 1, file) != 1) return LD10K1_LF_ERR_READ; /* check type & id */ if (part->part_type == part_type && part->part_id == part_id) { if (part->part_type == LD10K1_FP_TYPE_NORMAL) { if (il || part->part_length == part_length) return 0; else return LD10K1_LF_ERR_PART_SIZE; } else { if (part->part_length != 0) return LD10K1_LF_ERR_PART_SIZE; else return 0; } } else { if ((err = liblo10k1lf_skip_part(file, part)) < 0) return err; } } } int liblo10k1lf_find_part(FILE *file, unsigned int part_type, unsigned int part_id, unsigned int part_length, liblo10k1_file_part_t *part) { return liblo10k1lf_find_part_il(file, part_type, part_id, part_length, 0, part); } int liblo10k1lf_find_part_ws(FILE *file, unsigned int part_id, unsigned int part_length, liblo10k1_file_part_t *part) { return liblo10k1lf_find_part(file, LD10K1_FP_TYPE_NORMAL, part_id, part_length, part); } int liblo10k1lf_find_part_start(FILE *file, unsigned int part_id) { liblo10k1_file_part_t part; return liblo10k1lf_find_part(file, LD10K1_FP_TYPE_START, part_id, 0, &part); } int liblo10k1lf_find_part_end(FILE *file, unsigned int part_id) { liblo10k1_file_part_t part; return liblo10k1lf_find_part(file, LD10K1_FP_TYPE_END, part_id, 0, &part); } int liblo10k1lf_find_load_part_ws(FILE *file, unsigned int part_id, unsigned int part_length, void *where) { int err; liblo10k1_file_part_t part; if ((err = liblo10k1lf_find_part_ws(file, part_id, part_length, &part)) < 0) return err; if (fread(where, part_length, 1, file) != 1) return LD10K1_LF_ERR_READ; return 0; } int liblo10k1lf_can_load_file(FILE *file, unsigned int ft) { liblo10k1_file_header_t fhdr; liblo10k1_file_part_info_t file_info; int err; if (fread(&fhdr, sizeof(liblo10k1_file_header_t), 1, file) != 1) return LD10K1_LF_ERR_READ; /* check signature */ if (strcmp(fhdr.signature, LD10K1_FILE_SIGNATURE) != 0) return LD10K1_LF_ERR_SIGNATURE; /* now load file info part & check version */ if ((err = liblo10k1lf_find_load_part_ws(file, LD10K1_FP_INFO, sizeof(file_info), &file_info)) < 0) return err; if (file_info.minimal_reader_version_major > CREATER_MAJOR) return LD10K1_LF_ERR_VERSION; if (file_info.minimal_reader_version_major == CREATER_MAJOR && file_info.minimal_reader_version_minor > CREATER_MINOR) return LD10K1_LF_ERR_VERSION; if (file_info.minimal_reader_version_major == CREATER_MAJOR && file_info.minimal_reader_version_minor == CREATER_MINOR && file_info.minimal_reader_version_subminor > CREATER_SUBMINOR) return LD10K1_LF_ERR_VERSION; /* check file type */ if (file_info.file_type != ft) return LD10K1_LF_ERR_FILE_TYPE; return 0; } int liblo10k1lf_load_io(liblo10k1_get_io_t *ios, int count, int ptl, int pt, FILE *file) { int i, err; /* io list start */ if ((err = liblo10k1lf_find_part_start(file, ptl)) < 0) return err; for (i = 0; i < count; i++) { if ((err = liblo10k1lf_find_load_part_ws(file, pt, sizeof(liblo10k1_get_io_t), &(ios[i]))) < 0) return err; } if ((err = liblo10k1lf_find_part_end(file, ptl)) < 0) return err; return 0; } int liblo10k1lf_load_points(liblo10k1_point_info_t *points, int count, FILE *file) { int i, err; /* io list start */ if ((err = liblo10k1lf_find_part_start(file, LD10K1_FP_POINT_LIST)) < 0) return err; for (i = 0; i < count; i++) { if ((err = liblo10k1lf_find_load_part_ws(file, LD10K1_FP_POINT, sizeof(liblo10k1_point_info_t), &(points[i]))) < 0) return err; } if ((err = liblo10k1lf_find_part_end(file, LD10K1_FP_POINT_LIST)) < 0) return err; return 0; } int liblo10k1lf_load_pio(liblo10k1_dsp_pio_t *ios, int count, int ptl, int pt, FILE *file) { int i, err; /* io list start */ if ((err = liblo10k1lf_find_part_start(file, ptl)) < 0) return err; for (i = 0; i < count; i++) { if ((err = liblo10k1lf_find_load_part_ws(file, pt, sizeof(liblo10k1_dsp_pio_t), &(ios[i]))) < 0) return err; } if ((err = liblo10k1lf_find_part_end(file, ptl)) < 0) return err; return 0; } int liblo10k1lf_load_cs(liblo10k1_dsp_cs_t *css, int count, int ptl, int pt, FILE *file) { int i, err; /* io list start */ if ((err = liblo10k1lf_find_part_start(file, ptl)) < 0) return err; for (i = 0; i < count; i++) { if ((err = liblo10k1lf_find_load_part_ws(file, pt, sizeof(liblo10k1_dsp_cs_t), &(css[i]))) < 0) return err; } if ((err = liblo10k1lf_find_part_end(file, ptl)) < 0) return err; return 0; } int liblo10k1lf_load_hw(liblo10k1_dsp_hw_t *hws, int count, FILE *file) { int i, err; /* io list start */ if ((err = liblo10k1lf_find_part_start(file, LD10K1_FP_HW_LIST)) < 0) return err; for (i = 0; i < count; i++) { if ((err = liblo10k1lf_find_load_part_ws(file, LD10K1_FP_HW, sizeof(liblo10k1_dsp_hw_t), &(hws[i]))) < 0) return err; } if ((err = liblo10k1lf_find_part_end(file, LD10K1_FP_HW_LIST)) < 0) return err; return 0; } int liblo10k1lf_load_tram(liblo10k1_dsp_tram_grp_t *trams, int count, FILE *file) { int i, err; /* io list start */ if ((err = liblo10k1lf_find_part_start(file, LD10K1_FP_TRAM_LIST)) < 0) return err; for (i = 0; i < count; i++) { if ((err = liblo10k1lf_find_load_part_ws(file, LD10K1_FP_TRAM, sizeof(liblo10k1_dsp_tram_grp_t), &(trams[i]))) < 0) return err; } if ((err = liblo10k1lf_find_part_end(file, LD10K1_FP_TRAM_LIST)) < 0) return err; return 0; } int liblo10k1lf_load_tram_acc(liblo10k1_dsp_tram_acc_t *tram_accs, int count, FILE *file) { int i, err; /* io list start */ if ((err = liblo10k1lf_find_part_start(file, LD10K1_FP_TRAM_ACC_LIST)) < 0) return err; for (i = 0; i < count; i++) { if ((err = liblo10k1lf_find_load_part_ws(file, LD10K1_FP_TRAM_ACC, sizeof(liblo10k1_dsp_tram_acc_t), &(tram_accs[i]))) < 0) return err; } if ((err = liblo10k1lf_find_part_end(file, LD10K1_FP_TRAM_ACC_LIST)) < 0) return err; return 0; } int liblo10k1lf_load_ctl(liblo10k1_dsp_ctl_t *ctls, int count, FILE *file) { int i, err; /* io list start */ if ((err = liblo10k1lf_find_part_start(file, LD10K1_FP_CTL_LIST)) < 0) return err; for (i = 0; i < count; i++) { if ((err = liblo10k1lf_find_load_part_ws(file, LD10K1_FP_CTL, sizeof(liblo10k1_dsp_ctl_t), &(ctls[i]))) < 0) return err; } if ((err = liblo10k1lf_find_part_end(file, LD10K1_FP_CTL_LIST)) < 0) return err; return 0; } int liblo10k1lf_load_instr(liblo10k1_dsp_instr_t *instrs, int count, FILE *file) { int i, err; /* io list start */ if ((err = liblo10k1lf_find_part_start(file, LD10K1_FP_INSTR_LIST)) < 0) return err; for (i = 0; i < count; i++) { if ((err = liblo10k1lf_find_load_part_ws(file, LD10K1_FP_INSTR, sizeof(liblo10k1_dsp_instr_t), &(instrs[i]))) < 0) return err; } if ((err = liblo10k1lf_find_part_end(file, LD10K1_FP_INSTR_LIST)) < 0) return err; return 0; } int liblo10k1lf_load_patch(liblo10k1_dsp_patch_t **p, FILE *file) { int err; liblo10k1_file_patch_info_t pinfo; liblo10k1_dsp_patch_t *patch = NULL; /* io list start */ if ((err = liblo10k1lf_find_part_start(file, LD10K1_FP_PATCH)) < 0) return err; /* patch info */ if ((err = liblo10k1lf_find_load_part_ws(file, LD10K1_FP_PATCH_INFO, sizeof(liblo10k1_file_patch_info_t), &pinfo)) < 0) return err; patch = liblo10k1_patch_alloc(pinfo.in_count, pinfo.out_count, pinfo.const_count, pinfo.sta_count, pinfo.dyn_count, pinfo.hw_count, pinfo.tram_count, pinfo.tram_acc_count, pinfo.ctl_count, pinfo.instr_count); if (!patch) { err = LD10K1_ERR_NO_MEM; goto err; } strcpy(patch->patch_name, pinfo.patch_name); /* pins */ if ((err = liblo10k1lf_load_pio(patch->ins, patch->in_count, LD10K1_FP_PIN_LIST, LD10K1_FP_PIO, file)) < 0) return err; /* pouts */ if ((err = liblo10k1lf_load_pio(patch->outs, patch->out_count, LD10K1_FP_POUT_LIST, LD10K1_FP_PIO, file)) < 0) return err; /* consts */ if ((err = liblo10k1lf_load_cs(patch->consts, patch->const_count, LD10K1_FP_CONST_LIST, LD10K1_FP_CS, file)) < 0) return err; /* stas */ if ((err = liblo10k1lf_load_cs(patch->stas, patch->sta_count, LD10K1_FP_STA_LIST, LD10K1_FP_CS, file)) < 0) return err; /* hws */ if ((err = liblo10k1lf_load_hw(patch->hws, patch->hw_count, file)) < 0) return err; /* trams */ if ((err = liblo10k1lf_load_tram(patch->tram, patch->tram_count, file)) < 0) return err; /* tram_accs */ if ((err = liblo10k1lf_load_tram_acc(patch->tram_acc, patch->tram_acc_count, file)) < 0) return err; /* ctls */ if ((err = liblo10k1lf_load_ctl(patch->ctl, patch->ctl_count, file)) < 0) return err; /* instrs */ if ((err = liblo10k1lf_load_instr(patch->instr, patch->instr_count, file)) < 0) return err; if ((err = liblo10k1lf_find_part_end(file, LD10K1_FP_PATCH)) < 0) return err; *p = patch; return 0; err: if (patch) liblo10k1_patch_free(patch); return err; } int liblo10k1lf_load_dsp_setup(liblo10k1_file_dsp_setup_t **c, FILE *file) { liblo10k1_file_part_dsp_setup_t setup; int err; int i; liblo10k1_file_dsp_setup_t *cfg; if ((err = liblo10k1lf_find_load_part_ws(file, LD10K1_FP_DSP_SETUP, sizeof(setup), &setup)) < 0) return err; cfg = liblo10k1lf_dsp_config_alloc(); cfg->dsp_type = setup.dsp_type; /* alloc space */ if ((err = liblo10k1lf_dsp_config_set_fx_count(cfg, setup.fx_count)) < 0) goto err; if ((err = liblo10k1lf_dsp_config_set_in_count(cfg, setup.in_count)) < 0) goto err; if ((err = liblo10k1lf_dsp_config_set_out_count(cfg, setup.out_count)) < 0) goto err; if ((err = liblo10k1lf_dsp_config_set_patch_count(cfg, setup.patch_count)) < 0) goto err; if ((err = liblo10k1lf_dsp_config_set_point_count(cfg, setup.point_count)) < 0) goto err; /* load fx */ if ((err = liblo10k1lf_load_io(cfg->fxs, cfg->fx_count, LD10K1_FP_FX_LIST, LD10K1_FP_FX, file)) < 0) return err; /* load in */ if ((err = liblo10k1lf_load_io(cfg->ins, cfg->in_count, LD10K1_FP_IN_LIST, LD10K1_FP_IN, file)) < 0) return err; /* load out */ if ((err = liblo10k1lf_load_io(cfg->outs, cfg->out_count, LD10K1_FP_OUT_LIST, LD10K1_FP_OUT, file)) < 0) return err; /* load patches */ if ((err = liblo10k1lf_find_part_start(file, LD10K1_FP_PATCH_LIST)) < 0) return err; for (i = 0; i < cfg->patch_count; i++) { if ((err = liblo10k1lf_load_patch(&(cfg->patches[i]), file)) < 0) return err; } if ((err = liblo10k1lf_find_part_end(file, LD10K1_FP_PATCH_LIST)) < 0) return err; /* load points */ if ((err = liblo10k1lf_load_points(cfg->points, cfg->point_count, file)) < 0) return err; *c = cfg; return 0; err: if (cfg) liblo10k1lf_dsp_config_free(cfg); return err; } int liblo10k1lf_load_dsp_config(liblo10k1_file_dsp_setup_t **c, char *file_name, liblo10k1_file_info_t **fi) { FILE *file = NULL; int err; liblo10k1_file_info_t *i = NULL; file = fopen(file_name, "r"); if (!file) return LD10K1_LF_ERR_OPEN; if ((err = liblo10k1lf_can_load_file(file, LD10K1_FP_INFO_FILE_TYPE_DSP_SETUP)) < 0) goto err; if ((err = liblo10k1lf_load_file_info(file, &i)) < 0) goto err; if ((err = liblo10k1lf_load_dsp_setup(c, file)) < 0) goto err; *fi = i; fclose(file); return 0; err: if (i) liblo10k1lf_file_info_free(i); fclose(file); return err; } liblo10k1_file_info_t *liblo10k1lf_file_info_alloc() { liblo10k1_file_info_t *tmp = (liblo10k1_file_info_t *)malloc(sizeof(liblo10k1_file_info_t)); if (tmp) memset(tmp, 0, sizeof(liblo10k1_file_info_t)); return tmp; } void liblo10k1lf_file_info_free(liblo10k1_file_info_t *fi) { if (fi->name) free(fi->name); if (fi->desc) free(fi->desc); if (fi->creater) free(fi->creater); if (fi->author) free(fi->author); if (fi->copyright) free(fi->copyright); if (fi->license) free(fi->license); } int liblo10k1lf_save_dsp_patch(liblo10k1_dsp_patch_t *p, char *file_name, liblo10k1_file_info_t *fi) { FILE *file = NULL; int err; file = fopen(file_name, "w"); if (!file) return LD10K1_LF_ERR_OPEN; if ((err = liblo10k1lf_save_file_header(file, LD10K1_FP_INFO_FILE_TYPE_PATCH)) < 0) goto err; if ((err = liblo10k1lf_save_file_info(file, fi)) < 0) goto err; if ((err = liblo10k1lf_save_patch(p, file)) < 0) goto err; fclose(file); return 0; err: fclose(file); return err; } int liblo10k1lf_load_dsp_patch(liblo10k1_dsp_patch_t **p, char *file_name, liblo10k1_file_info_t **fi) { FILE *file = NULL; int err; liblo10k1_file_info_t *i = NULL; file = fopen(file_name, "r"); if (!file) return LD10K1_LF_ERR_OPEN; if ((err = liblo10k1lf_can_load_file(file, LD10K1_FP_INFO_FILE_TYPE_PATCH)) < 0) goto err; if ((err = liblo10k1lf_load_file_info(file, &i)) < 0) goto err; if ((err = liblo10k1lf_load_patch(p, file)) < 0) goto err; *fi = i; fclose(file); return 0; err: if (i) liblo10k1lf_file_info_free(i); fclose(file); return err; }